arjacsoh
arjacsoh

Reputation: 9232

Passing an object as reference or pointer in a function

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

Answers (6)

Steve Jessop
Steve Jessop

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

Tadeusz Kopec for Ukraine
Tadeusz Kopec for Ukraine

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:

  • If you want to modify argument and the caller may not provide it, pass by pointer (and pass NULL, 0 or nullptr for no object).
  • If you want to modify argument and object must be passed to function - pass by reference.
  • If you don't want to modify argument but the caller may not provide it, pass by const pointer
  • Otherwise if object is expensive to copy pass by const reference, if not, pass by value.
  • New feature - if you want to copy argument inside a function (e.g. pass a string in constructor to initialize a field) and you use C++11 compliant compiler (support for move constructors), pass by value.

Upvotes: 1

Jagannath
Jagannath

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

Blagovest Buyukliev
Blagovest Buyukliev

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

ibid
ibid

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

triclosan
triclosan

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

Related Questions