I know that the question “when pointer and when reference” or “pass an argument in function by reference or pass by pointer” has been asked numerous times. However, I have the impression that in a few occasions I have read: “You should pass an Object to a function by pointer when you want to modify it”. Could someone say, explain and justify if the last sentence is entirely correct?
Or in other words, isn’t it possible to modify an object through a reference?
You should pass an object as a double pointer if you want to change what the pointer points to, for example when moving the object from one memory location to another:
void foo (obj **x) {
delete *x;
obj *y = (obj *) some_new_address;
*x = y; // change what x points to
}
...
obj *x = new obj();
foo(&obj);
// obj now points to another location
With a reference you can't do that.
For convenience, I'll refer to a parameter that is modified by the function as an "out-param".
Out-params can be passed as non-const references. There's no technical reason not to. In the standard libraries, for example, std::swap takes two parameters by reference and modifies both.
I have in the past seen, as a rule in a style guide, that out-params must be passed by pointer rather than by reference. The motivation behind this is that some people[*] want a function call that appears to pass the object by value, to leave the object unmodified. This makes it easier for them to reason about a piece of code just by looking at the calling code, without needing to look up what the function actually does. For example:
int foo(int a) {
return a + 1;
}
int bar(int &a) {
return ++a;
}
Now, given int i = 0;, the calls foo(i) and bar(i) look exactly the same, but one of them behaves like a nice, simple C function whereas the other one uses pass-by-reference to modify i.
Some people[*] want those different things to be obviously different at the call site, so they'd prefer to write bar(&i) to make it clear that i could be modified[**]. Basically, they'd prefer that C++ didn't have non-const references as function parameters at all.
There isn't necessarily anything wrong with that these people want to do. You can for example stick to it in the case of std::swap by always using std::iter_swap instead. But most C++ style guides don't have any such rule.
[*] for example C programmers
[**] In fact in my bar function, a is both an in-param and an out-param. Their preferred function int bar(int *pa); technically doesn't have an out-param, although for convenience they'd probably refer to the referand of pa (that is, i) as an out-param and everyone knows what that means.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With