Are There Benefits of Passing by Pointer Over Passing by Reference in C++

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.

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 pointer" - no need to look up function definition
func2(&mySprite);

When pass-by-pointer is preferred to pass-by-reference in C++?

Some like pass-by-pointer better in cases where the object being passed is actually going to be modified. They use pass-by-const-reference when the object is being passed by reference in order to avoid a copy of the object, but will not be changed in the function.

In illustration, take the following functions:

int foo(int x);
int foo1(int &x);
int foo2(int *x);

Now in the code, I do the following:

int testInt = 0;

foo(testInt); // can't modify testInt
foo1(testInt); // can modify testInt

foo2(&testInt); // can modify testInt

In calling foo vs foo1, it's not apparent from the callers perspective (or a programmer reading the code) that the function can modify testInt without having to look at the signature of the function. Looking at foo2, a reader can easily see that the function may in fact modify the value of testInt because the function is receiving the address of the parameter. Note that this doesn't guarantee the object is actually modified, but that's where being consistent in the use of references vs. pointers helps. In general, if you want to follow this guideline consistently you should always pass const references when you want to avoid copies, and pass by pointer when you want to be able to modify the object.

Passing by reference in C

Because you're passing the value of the pointer to the method and then dereferencing it to get the integer that is pointed to.

Why, or in what situations, would you pass an argument to a function as a reference (or pointer) in C++?

There are essentially three reasons why this is done.

Reduced memory usage

Every time you call a function the arguments are copied and passed. This isn't a big deal when you are passing around numbers. However when you are dealing with big chunks of memory, like objects, structs, arrays etc. this becomes very expensive.

So all complex types are typically passed as pointers. If you are throwing around objects you are always working with a pointer.

The const qualifier should be used in this instance to indicate that the variable won't be changed.

Modify the argument

Sometimes it is useful to modify the passed argument, though this should be avoided as bad style. The best example I think is modifying an array, for example a push() function. Another is modifying an objects public members, or when you want to return multiple values from a function.

Note that this can be a source of bugs. If you are modifying a passed variable it should be obvious from the name of the function that this is what you are doing.

Low level memory access

Anything which directly works with memory will want direct access to said memory. Standard practice in C but less common in C++. Look at functions like memcpy() and anything else from <string.h>.

Pass by Reference v. Pass by Pointer -- Merits?

The main difference is that a reference cannot be NULL (at least not without some malicious programming). For syntactical sugar and when an argument is required, I'd pass by reference. If I had a situation where the argument were optional, I'd pass by pointer.

There are always exceptions. If it conforms to the current style, or due to things I have to do with it, it may be more convenient to have it as a pointer.

Performance cost of passing by value vs. by reference or by pointer?

It depends on what you mean by "cost", and properties of the host system (hardware, operating system) with respect to operations.

If your cost measure is memory usage, then the calculation of cost is obvious - add up the sizes of whatever is being copied.

If your measure is execution speed (or "efficiency") then the game is different. Hardware (and operating systems and compiler) tend to be optimised for performance of operations on copying things of particular sizes, by virtue of dedicated circuits (machine registers, and how they are used).

It is common, for example, for a machine to have an architecture (machine registers, memory architecture, etc) which result in a "sweet spot" - copying variables of some size is most "efficient", but copying larger OR SMALLER variables is less so. Larger variables will cost more to copy, because there may be a need to do multiple copies of smaller chunks. Smaller ones may also cost more, because the compiler needs to copy the smaller value into a larger variable (or register), do the operations on it, then copy the value back.

Examples with floating point include some cray supercomputers, which natively support double precision floating point (aka double in C++), and all operations on single precision (aka float in C++) are emulated in software. Some older 32-bit x86 CPUs also worked internally with 32-bit integers, and operations on 16-bit integers required more clock cycles due to translation to/from 32-bit (this is not true with more modern 32-bit or 64-bit x86 processors, as they allow copying 16-bit integers to/from 32-bit registers, and operating on them, with fewer such penalties).

It is a bit of a no-brainer that copying a very large structure by value will be less efficient than creating and copying its address. But, because of factors like the above, the cross-over point between "best to copy something of that size by value" and "best to pass its address" is less clear.

Pointers and references tend to be implemented in a similar manner (e.g. pass by reference can be implemented in the same way as passing a pointer) but that is not guaranteed.

The only way to be sure is to measure it. And realise that the measurements will vary between systems.

Pass by pointer & Pass by reference

A reference is semantically the following:

T& <=> *(T * const)

const T& <=> *(T const * const)

T&& <=> [no C equivalent] (C++11)

As with other answers, the following from the C++ FAQ is the one-line answer: references when possible, pointers when needed.

An advantage over pointers is that you need explicit casting in order to pass NULL.
It's still possible, though.
Of the compilers I've tested, none emit a warning for the following:

int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}

Differences between passing by reference and passing by address

Let me try to make you understand in easy way. When you declared any variable in your c++ program then compiler create an entry in the symbol table for that variable and later an appropriate space in memory provided for it.
In case of reference variable there will be a new entry in the symbol table which having the same storage of referenced varible, there will be no space allocated for it later, it is just an alias name like you may be refer by two names (like name, nick name).
Now lets take a case of pointer varible. Irrespective of it is a pointer but it is a variable so it will also have a symbol table entry and space will be allocated for it later.

So from above statements you can easily find the below difference between address(pointer) and reference variable
1) There will no extra memory allocated for the reference variable but for pointer variable there will be 4 or 8 bytes depends on the system (32 or 64 bit operating system) for which you are going to compile and run the code.
2) you can't deference the reference variable later on normally so you can't changed the reference but in case of pointer variable it can contain different pointer.

The same is applicable for passing by reference and passing by address. Hope it will help you to understand in better way.

Try execute the below code and you will find that the address of variable and reference variable is same

int main()
{
int i = 10;
int& j = i;

printf(" address of i = %u address of j = %u", &i, &j);
return 0;
}

What is more efficient: pass parameter by pointer or by value?

In nearly all code, as long as we're dealing with small/simple objects, the overhead of copying the object, vs. passing it as a pointer or reference is pretty small.

Obviously, if we make a std::string with a large chunk of text in it, it will take quite some time to copy it, relative to just passing a reference.

However, the primary objecting ANY TIME when writing code is to focus on correctness. If you have "large" objects, then use const Type &val if the value is not being modified - that way, you can't accidentally modify it. If the object is to be modified, then you NEED to use a reference or pointer to get the updates back to the caller of the function.

It is entirely possible to make code that runs noticeably slower with a reference than with a value. I was once looking into the performance of some code that we were working on, and found a function that looked something like this:

void SomeClass::FindThing(int &thing)
{
for(thing = 0; someVector[thing] != 42; thing++)
;
}

It really looks rather innocent, but since each update of thing means an indirect memory access [at least in the compiler we used, which was certainly not "rubbish"], it was taking quite a lot of time out of the entire process [it was also called twice as much as necessary].

I rewrote it as:

void SomeClass::FindThing(int &thing)
{
for(int i = 0; someVector[i] != 42; i++)
;
thing = i;
}

And the function ran about 4x faster. Taking out the second, unnecessary call, as well, and we ended up with about 30% faster runtime. This was in a "fonts benchmark", and this was one out of a several dozen functions involved in the "draw fonts to screen". It's scary how a simple, innocent looking function can make a BIG difference to performance.



Related Topics



Leave a reply



Submit