Are there benefits of passing by pointer over passing by reference in C++?

A pointer can receive a NULL parameter, a reference parameter can not. If there's ever a chance that you could want to pass "no object", then use a pointer instead of a reference.

Up vote 27 down vote favorite 10 share g+ share fb share tw.

Lately, I have seen a number of examples that pass the a pointer instead of passing by reference. Are there benefits to doing this? Example: func(SPRITE *x); with a call of func(&mySprite); vs. func(SPRITE &x); with a call of func(mySprite); c++ pointers pass-by-reference argument-passing link|improve this question edited Dec 2 '08 at 18:18Greg Rogers12k32461 asked Dec 2 '08 at 17:58Matt Pascoe93311225 89% accept rate.

A pointer can receive a NULL parameter, a reference parameter can not. If there's ever a chance that you could want to pass "no object", then use a pointer instead of a reference. Also, passing by pointer allows you to explicitly see at the call site whether the object is passed by value or by reference: // Is mySprite passed by value or by reference?

You can't tell // without looking at the definition of func() func(mySprite); // func2 passes by reference - no need to look up function definition func2(&mySprite).

Great answer - it would be even better with a quick edit of the first code comment such that it doesn't overflow and cause a scrollbar. Yes, I'm pedantic! – Bobby Jack Dec 3 '08 at 0:29 2 Incomplete answer.

Using pointers won't authorize uses of temporary/promoted objects, nor the use of pointed object as stack-like objects. And it will suggest that the argument can be NULL when, most of the time, a NULL value should be forbidden. Read litb's answer for a complete answer.

– paercebal Dec 3 '08 at 10:12.

Passing by pointer Caller has to take the address -> not transparent A 0 value can be provided to mean nothing. This can be used to provide optional arguments. Pass by reference Caller just passes the object -> transparent.

Has to be used for operator overloading, since overloading for pointer types is not possible (pointers are builtin types). So you can't do string s = &str1 + &str2; using pointers. No 0 values possible -> Called function doesn't have to check for them Reference to const also accepts temporaries: void f(const T& t); ... f(T(a, b, c));, pointers cannot be used like that since you cannot take the address of a temporary.

Last but not least, references are easier to use -> less chance for bugs.

1 Good points for either sides of the argument. As far as I am concerned, your answer is THE answer. +1.

– paercebal Dec 3 '08 at 10:09 1 Passing by pointer also raises the 'Is ownership transferred or not? ' question. This is not the case with references.

– Frerich Raabe Oct 30 '09 at 17:53 You should probably add that it is cleaner to use pointer when there is ownership transfer, or for registering callbacks (item that must survive the current stack frame). – Sylvain Defresne Mar 16 '11 at 13:56 I disagree with "less chance for bugs". When inspecting the call site and the reader sees "foo( &s )" it is immediately clear that s may be modified.

When you read "foo( s )" it is not at all clear if s may be modified. This is a major source of bugs. Perhaps there is less chance of a certain class of bugs, but overall, passing by reference is a huge source of bugs.

– William Pursell Nov 21 '11 at 14:10.

Allen Holub's "Enough Rope to Shoot Yourself in the Foot" lists the following 2 rules: 120. Reference arguments should always be `const` 121. Never use references as outputs, use pointers He lists several reasons why references were added to C++: they are necessary to define copy constructors they are necessary for operator overloads const references allow you to have pass-by-value semantics while avoiding a copy His main point is that references should not be used as 'output' parameters because at the call site there's no indication of whether the parameter is a reference or a value parameter.

So his rule is to only use const references as arguments. Personally, I think this is a good rule of thumb as it makes it more clear when a parameter is an output parameter or not. However, while I personally agree with this in general, I do allow myself to be swayed by the opinions of others on my team if they argue for output parameters as references (some developers like them immensely).

1 My stance in that argument is that if the function name makes it totally obvious, without checking the docs, that the param will be modified, then a non-const reference is OK. So personally I'd allow "getDetails(DetailStruct &result)". A pointer there raises the ugly possibility of a NULL input.

– Steve Jessop Dec 2 '08 at 19:06 @onebyone - that seems like another good rule of thumb – Michael Burr Dec 2 '08 at 19:45 1 This is misleading. Even if some do not like references, they are a important part of the language and should be used as that. This line of reasoning is like saying don't use templates you can always use containers of void* to store any type.

Read answer by litb. – David Rodríguez - dribeas Dec 2 '08 at 20:28 1 I don't see how this is misleading - there are times when references are required, and there are times when best practices might suggest not using them even if you could. The same can be said for any feature of the language - inheritance, non-member friends, operator overloading, MI, etc... – Michael Burr Dec 2 '08 at 21:34 By the way, I agree that litb's answer is very good, and is certainly more comprehensive than this one - I just elected to focus on discussing a rationale for avoiding using references as output parameters.

– Michael Burr Dec 2 '08 at 21:38.

Not really. Internally, passing by reference is performed by essentially passing the address of the referenced object. So, there really aren't any efficiency gains to be had by passing a pointer.

Passing by reference does have one benefit, however. You are guaranteed to have an instance of whatever object/type that is being passed in. If you pass in a pointer, then you run the risk of receiving a NULL pointer.

By using pass-by-reference, you are pushing an implicit NULL-check up one level to the caller of your function.

Thats both an advantage and a disadvantage. Many APIs use NULL pointers to mean something useful (ie NULL timespec wait forever, while the value means wait that long). – Greg Rogers Dec 2 '08 at 18:17 @Brian: I don't want to be nit-picking but: I would not say one is guaranteed to get an instance when getting a reference.

Dangling references are still possible if the caller of a function de-references a dangling pointer, which the callee cannot know. – foraidt Dec 2 '08 at 18:18 sometimes you can even gain performance by using references, since they don't need to take any storage and don't have any addresses assigned for themself. No indirection required.

– Johannes Schaub - litb Dec 2 '08 at 18:22 Programs which contain dangling references are not valid C++. Therefore, yes, the code can assume that all references are valid. – Konrad Rudolph Dec 2 '08 at 18:26 I can definitely dereference a null pointer and the compiler won't be able to tell... if the compiler can't tell it's "invalid C++", is it really invalid?

– rmeador Dec 2 '08 at 18:34.

Clarifications to the preceding posts: References are NOT a guarantee of getting a non-null pointer. (Though we often treat them as such. ) While horrifically bad code, as in take you out behind the woodshed bad code, the following will compile & run: (At least under my compiler.

) bool test( int & a) { return (&a) == (int *) NULL; } int main() { int * I = (int *)NULL; cout Deallocation in destructor gets invoked twice. ) Thankfully modern compilers will pick up this double-deallocation of the same pointer. 15 years ago, they didn't.

(Under gcc/g++, use *setenv MALLOC_CHECK_ 0* to revisit the old ways. ) Resulting, under DEC UNIX, in the same memory being allocated to two different objects. Lots of debugging fun there... More practically: References hide that you are changing data stored someplace else.

It's easy to confuse a Reference with a Copied object. Pointers make it obvious!

1 that's not the problem of the function or references. You are breaking language rules. Dereferencing a null pointer by itself is already undefined behavior.

"References are NOT a guarantee of getting a non-null pointer. ": the standard itself says they are. Other ways constitute undefined behavior.

– Johannes Schaub - litb Dec 3 '08 at 4:47 I agree with litb. While true, the code you are showing us is more sabotage than anything else. There are ways to sabotage anything, including both the "reference" and "pointer" notations.

– paercebal Dec 3 '08 at 10:00 I did say it was "take you out behind the woodshed bad code"! In the same vein, you can also have i=new FOO; delete i; test(*i); Another (unfortunately common) dangling pointer/reference occurrence. – Mr.Ree Dec 3 '08 at 17:32 It's actually not dereferencing NULL that's the problem, but rather USING that dereferenced (null) object.

As such, there really is no difference (other than syntax) between pointers and references from a language-implementation perspective. It's the users who have different expectations. – Mr.Ree Dec 3 '08 at 17:33.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions