7

Is it generally considered better to pass parameters as pointers rather than as value when you can? Obviously it largely depends on the situation, but when there is a choice, is it better to use pointers?

Is this simply for reasons of memory?

And what is better to pass through if it is true, a pointer or a reference?

sehe
  • 374,641
  • 47
  • 450
  • 633
Dollarslice
  • 9,917
  • 22
  • 59
  • 87

5 Answers5

10

Some general rules of thumb:

If you need to modify it, pass a pointer or a reference. If the value might be null, pass a pointer, otherwise pass a reference.

If it's large, pass a const pointer or const reference, depending on whether null is a legal value.

If using pointers, prefer smart pointers to bare pointers.

Otherwise, pass by value.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • 2
    ... an intentionally relative term. The question is both whether it costs more to copy the value than a pointer to the value, and whether it matters. Personally, anything more than 8 bytes or so, and I tend to pass a pointer or reference. – Andy Thomas Oct 13 '11 at 13:42
  • ... also could be meant to mean "anything that requires a non-trivial copy constructor" perhaps, though that usually entails a "large" size. – Kerrek SB Oct 13 '11 at 14:08
  • I was alluding to that in "costs more to copy," but should have been explicit. Size is usually the cause of copy cost, but it's not the only thing. – Andy Thomas Oct 13 '11 at 14:30
  • what's the difference between passing a pointer/reference and a const pointer/reference? and why is one preferred if the object is 'large'? – Dollarslice Oct 13 '11 at 14:48
  • @SirYakalot: If you would normally pass something by value and decide to pass it by ptr/reference instead (for whatever reason), you would prefer to pass by `const` reference as opposed to non-`const` reference. This is because when you pass by value the function cannot modify the caller's copy of the value. Therefore to maintain the same semantics, pass by `const` reference since by passing by non-`const` reference the function *could* change the caller's value. Hope this makes sense. – John Dibling Oct 13 '11 at 14:57
  • @SirYakalot - For your second question, copying a pointer or reference is usually a cheap, constant-time copy of four or eight bytes, regardless of the size of the object to which it points and the cost of its copy. – Andy Thomas Oct 13 '11 at 15:43
2

In C++, when you pass by value, it calls the copy constructor for custom classes. This can be really expensive if you are passing vectors or large data structures.

You should use const and reference to not copy it and still protect the value. Otherwise, using value for smaller things like ints is typically reasonable.

Donald Miner
  • 38,889
  • 8
  • 95
  • 118
0

It best practive to NEVER pass a pointer.

  1. Pass by const reference to avoid the cost of copying.

  2. Pass by reference if you want the function to modify the original.

  3. Otherwise pass by value.

  4. Pointers should never by passed in the RAW (no ownership semantics)
    Pointers should never be held outside a smart pointer or a container class.

  5. Only if the object can potentially be NULL and ownership is explicitly not passed (via lots of documentation) should you ever pass a pointer.

The only time I expect to see a pointer is when I can not use a reference (ie it could be NULL) and that is practically never (or wrapped deep inside a container method).

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 7
    The word *never* should **NEVER** be used. There're instances where you've to pass pointers, especially when the `NULL` may be a valid argument to a function, then *references* may not make sense; smart pointers may not be used. – Nawaz Oct 13 '11 at 13:37
  • 3
    Best practices are not all inclusive. Thus NEVER is appropriate. Best to start of NEVER doing it then once you understand the language learn the exceptions. – Martin York Oct 13 '11 at 13:45
  • Loki: The phrase *best practices* doesn't mean ALWAYS. There are *few* instances where *best practices* are in fact worse practices. – Nawaz Oct 13 '11 at 13:50
  • @Nawaz: Yes. Thus it is best to always use "best practice" until you understand when not to do it. Hence best practice and not a law. – Martin York Oct 13 '11 at 13:53
  • Loki: Yes. But the bold and capitalized **NEVER** in your answer, means only *never*. It does not mean `it is always use "best practice" until you understand when not to do it.` – Nawaz Oct 13 '11 at 14:00
  • That's what "Best Practice" means. It is best "NEVER" to do this. But "Best Paractice" does not mean always it just means it is best "NEVER" to do this. Until you understand when not to do it. Thus it is best to "NEVER" do it. – Martin York Oct 13 '11 at 14:16
  • Loki: You're contradicting yourself. What does "never" means? Especially when it is written as **NEVER** (capitalized and bold)? – Nawaz Oct 13 '11 at 14:20
  • @Nawaz: I see no contradiction in my statement. I see a lack of understanding of what "Best Practice" means in yours. – Martin York Oct 13 '11 at 14:22
  • Loki: When you use **NEVER** in capitalized and bold text, then you're contradictory. When you say *it is always use "best practice" until you understand when not to do it*, then it makes **MORE SENSE** than your answer itself. (and when I used "more sense" in capitalized and bold text, I **SERIOUSLY** mean it.) – Nawaz Oct 13 '11 at 14:35
  • @Nawaz: Now you are making **NO SENSE**. Absolutely **SERIOUS** about that. It just takes a dictionary to look up "Best Practice". Google is your friend :-) – Martin York Oct 13 '11 at 14:44
  • 2
    @Andy Thomas-Cramer: I would prefer not to use pointers (but unfortunately I need to sometimes), but best practice is still never to use them. :-) – Martin York Oct 13 '11 at 16:27
0

It depends on which kind of parameter you are passing. If the parameter size is reasonably (again, decided by you) low then you may want to pass by value.

For large size structs/arrays it is always a good practice to pass by pointer or reference. On top of this, if the parameter is not supposed to be modifiable then you may also add const.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
0

I usually pass by reference (possible a const one) for input parameters, and by pointers for output parameters.

This way it is immediately visible which parameters are input ones and which parameters are the output ones (the callee modify their content).

Of course, form small types like int, long etc I don't bother with references.

Paolo Brandoli
  • 4,681
  • 26
  • 38
  • Input parameters may be passed by either references or pointers. A const-qualified pointer or reference indicates an input parameter. A non-const-qualified pointer or reference indicates either an output parameter or const-incorrectness. – Andy Thomas Oct 13 '11 at 13:58