Reputation: 9232
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?
Upvotes: 3
Views: 10816
Reputation: 279215
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.
Upvotes: 4
Reputation: 12403
Of course it is possible to modify an object through a reference. Maybe the sentence you quote was about C, which has no references?
The guideline is like this:
Upvotes: 1
Reputation: 4025
To pass a variable as an out parameter, you can pass it as a reference as well as a pointer. Try only use pointers if the variable has to live longer than it's scope. For eg. returning a pointer from a function to the callee.
In some cases, if you can't allocate memory on the stack, then use pointers and allocate memory on the heap. Again can pass the pointer to a function as an out parameter either by pointer or by reference.
Upvotes: 0
Reputation: 43498
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.
Upvotes: 4
Reputation: 3902
The sentence you quote is normative, that is, it tells you what you "should" do, not what you "can" or "cannot" do. As such, it's a matter of style and subject to debate. I personally do not accept it.
It certainly is possible to modify an object through a (non-const
) reference.
Upvotes: 2
Reputation: 5714
you can modify your object both ways by reference and by pointer. If you do not want modify you can use const
modifier.
Upvotes: 0