0

I'm wondering if there is any difference between passing an object reference as a parameter or as an argument. Is the code below equivalent? Is there situations where I should use one or the other?

void foo(Object &object){
    object.update()
}

 Object object
 foo(object)

VS

void bar(Object *object){
     object->update()
}

Object object
bar(&object)
Aaron B
  • 97
  • 1
  • 1
  • 7
  • Your terminology doesn't make much sense. Having said that, yes indeed these two pieces are essentially equivalent. – Igor Tandetnik Jul 15 '16 at 14:33
  • ... with the added caveat that the second one can crash because of a null pointer dereference, while you have to jump through hoops to make that happen in the first case. – dhke Jul 15 '16 at 14:35
  • Note that in `bar` you might be passed a null `Object*`, whereas it is impossible to have a "null reference" (almost impossible, highly unlikely). A good rule of thumb to use when designing your functions is "if the argument can be null, use a pointer (and check the pointer in your function), and if the argument can not be null, use a reference" – Steve Lorimer Jul 15 '16 at 14:36
  • Unrelated to your question, but it looks like [this SO question](http://stackoverflow.com/questions/156767/whats-the-difference-between-an-argument-and-a-parameter) can help clear up some of your terminology in terms of the difference between an argument and a parameter – Steve Lorimer Jul 15 '16 at 14:42

2 Answers2

1

You seem a bit confused. None of your examples pass by value. First example passes by reference, the second passes by pointer.

The main differences are:

Pass by value foo(Object object): the function gets a copy of the argument and cannot change the original.

Pass by reference foo(Object& object): the function gets a reference (not copy) to the original object and can modify it. References cannot be "un-bound", they always refer to a valid object (with certain exceptions which are usually bugs).

Pass by pointer foo(Object* object): as passing by reference, except it is valid for the pointer to not refer to anything (it can be nullptr which is useful if you need to signal that).

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • 2
    Strictly speaking the second one is passing a pointer **by value** – Steve Lorimer Jul 15 '16 at 14:38
  • Reference can be constructed from `null` pointer as well, you just have no way of checking that. – Agent_L Jul 15 '16 at 14:39
  • 1
    Ok, ok, but now you are being pedantic. – Jesper Juhl Jul 15 '16 at 14:40
  • The whole point of discussing C++ is being overly pedantic : ) – Agent_L Jul 15 '16 at 14:40
  • @Agent_L forming a reference from a null pointer involves dereferencing it, which is UB. – Quentin Jul 15 '16 at 14:42
  • @Agent_L creating a reference from a null pointer is undefined behaviour and will typically result in a segmentation fault at the pointing of dereferencing the null pointer – Steve Lorimer Jul 15 '16 at 14:43
  • sorry didnt mean to put value in title, I meant what the difference between foo(object) vs bar(&object) both seem like the same way to do something. but I was wondering if they really were, and if there were situations I should do one or the other. – Aaron B Jul 15 '16 at 14:47
0

When you take by reference and the function can be inlined, the compiler is - theoretically - not required to generate the address of the instance. Depending on your type, unary prefix operator&() might do more than just returning this. Also, it's valid for a pointer to be nullptr, you should check for that (or use gsl's not_null).

lorro
  • 10,687
  • 23
  • 36