3

So, I have a class which stores a vector of pointers to objects. I have a method that adds objects to the vector. When adding, I know I can pass by reference or by pointer, and have read about the advantages and disadvantages of each, but in this case, I can't figure out which one is better and why. For all I can figure out, they're pretty much the same (but I'm probably wrong!)

Here's (a paraphrasing of) passing by pointer/address:

hpp:
class Room {
    vector<Item*> items;
public:
    void addItem(Item*);
};

cpp:
void Room :: addItem(Item* item) {
    items.push_back(item);
}

...and pass by reference:

hpp:
class Room {
    vector<Item*> items;
public:
    void addItem(Item &);
};

cpp:
void Room :: addItem(Item &item) {
    items.push_back(&item);
}

Which should I use?

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
Jean Finley
  • 507
  • 3
  • 9
  • 21
  • 1
    Is it valid to pass a null pointer to `addItem`? My preference would be neither, but to use `unique_ptr` or `shared_ptr` to make the ownership semantics clearer. – aschepler Jul 11 '12 at 23:04

4 Answers4

5

It doesn't matter in the slightest, so do whatever seems more natural at the call site, or is more consistent with the rest of the code.

OK, I can see points in favour of each, but I can't tell you if they matter in your case.

  • passing by pointer more accurately reflects how you're using the argument (although I can't tell whether that's useful semantic info or an implementation detail)
    • a call site passing a pointer (or the result of new directly) will look natural
    • a call site doing something stupid like passing the address of an automatic variable will stand out
  • passing by reference suggests the argument should not be NULL, which may or may not be correct and useful
Useless
  • 64,155
  • 6
  • 88
  • 132
1

Whichever, depending on the context of the rest of your programme.

Both will work fine, so it's more a question of which will make the code clearer.

hcarver
  • 7,126
  • 4
  • 41
  • 67
1

Technically, both are equivalent ways of passing and will work equally well. However, at design level, there are differences regarding how these interfaces may be interpreted by user, what contract is promised. It's also matter of self-descripting interfaces.

At first glance, the by-pointer version says: item may be pointer to an existing object or it may be nullptr (likely, addItem does test the pointer and reacts), whereas the by-reference version indicates, the item must refer to an existing object (caller must guarantee that, so addItem does not have to test it).

Simply, chosing the syntax is also a matter of expressing your intentions clearly and unambiguously.

mloskot
  • 37,086
  • 11
  • 109
  • 136
0

It's a matter of (your) preference in syntax, as this is not a case where references provide some benefit over pointers, or vice versa. I suggest you go with pointers so that it is immediately evident to someone who's reading client code (which makes use of the Room Type) that you're passing items by reference - not by value.

biril
  • 1,975
  • 1
  • 19
  • 30
  • -1 because passing by pointer isn't passing by reference. Passing a pointer is pass by value. – Luchian Grigore Jul 11 '12 at 23:06
  • Passing by reference means that you have the same object inside the function. If you pass a pointer directly, it points to the same location, but it's not the same pointer. A copy of the pointer is created. – Luchian Grigore Jul 11 '12 at 23:11
  • I got what he/she meant. Cheers =) – Jean Finley Jul 11 '12 at 23:12
  • Agreed. You pass the pointer _by value_. But you're passing the pointed-to object _by reference_. – biril Jul 11 '12 at 23:13
  • When you pass a pointer as a parameter you can simulate 'passing by reference' manipulating the content of the pointed value, but, the reference itself is still passed by value, so both of you are right/wrong, =) – higuaro Jul 11 '12 at 23:15
  • "But you're passing the pointed-to object by reference" **no**. You're not passing the object. You're only passing the pointer. – Luchian Grigore Jul 11 '12 at 23:20
  • @h3nr1x "but, the reference itself is still passed by value" - no. There's no reference passed. The only argument is a pointer. And that's passed by value. Simple as that. – Luchian Grigore Jul 11 '12 at 23:20
  • Guys come on now, it is a(n important) matter of definition. In the expression foo(&bar), bar is passed by reference. In the expression 'foo(bar)' bar is passed by value. No? – biril Jul 11 '12 at 23:21
  • @LuchianGrigore Sorry, it was a typo, I wanted to say "pointer". And yes, it is passed by value, but you can modify the content of the pointed value and with this you can simulate 'passing by reference' – higuaro Jul 11 '12 at 23:26
  • @h3nr1x yes, agreed, but that hardly means "the reference itself is still passed by value" – Luchian Grigore Jul 11 '12 at 23:27
  • @biril absolutely not. Pass by reference or value is determined by the function signature, not by whether you put `&` before the variable or not. "foo(&bar), bar is passed by reference" - no. It means you pass the *address* of `bar` to the function. It could be by reference if the signature was `foo(Bar*& b)`. – Luchian Grigore Jul 11 '12 at 23:28
  • @LuchianGrigore ok, now I understood your point – higuaro Jul 11 '12 at 23:28
  • @LuchianGrigore So you're claiming that in plain old C where there is no such thing as 'reference variables', you _cannot_ 'pass by reference'? – biril Jul 11 '12 at 23:32
  • @biril No, in C you can't pass by reference, but you can simulate pass by reference with passing a pointer. I never said you couldn't. Anyway, it doesn't mean anything, since the question is about C++. See http://stackoverflow.com/questions/2229498/passing-by-reference-in-c – Luchian Grigore Jul 11 '12 at 23:37
  • Also this http://clc-wiki.net/wiki/C_language:Terms:Pass_by_reference – Luchian Grigore Jul 11 '12 at 23:37
  • "C does not directly support pass by reference because it always uses pass by value, but a programmer can implement pass by reference by passing a pointer to the variable that the programmer wants passed by reference." – Luchian Grigore Jul 11 '12 at 23:38
  • You can either take something from this whole discussion, or be stubborn and hold your point of view (which is wrong), your choice. Either way, I'm not going to continue this discussion as I don't feel it's productive (you seem reluctant to learn). – Luchian Grigore Jul 11 '12 at 23:39
  • I understand what you're saying. I only wanted to make sure that I did. It is your choice to call it 'pass by pointer' or 'simulated pass by reference' or whatever. And maybe you would be right in doing that as it avoids any confusion with 'reference variables'. Just note that there is a _great deal_ of literature which refers to passing pointers to objects as 'passing by reference'. No links needed, a simple google search for 'pass by reference' will demonstrate this. It's as simple as that. – biril Jul 11 '12 at 23:48
  • @LuchianGrigore Any chance you could reply to my question on your answer? Thanks. – Jean Finley Jul 11 '12 at 23:58
  • 1
    There is a lot of confusion about what "pass by reference" really means and I think the definition is different depending on the language. I suggest everyone read [the answer to this SO question](http://stackoverflow.com/questions/410593/pass-by-reference-value-in-c) for an overview of the C++ definition. – Jesse Good Jul 12 '12 at 00:00
  • @JesseGood that's good material, as it relates to this discussion. (Sorry we strayed so far from the original question though, Jean) – biril Jul 12 '12 at 00:10
  • Had to get some sleep, will answer now. There's no mention of references or pass-by-reference in C99. The only thing remotely close to this is `§6.5.2.2 - Function calls` - a footnote that says "A function may change the values of its parameters, but these changes cannot affect the values of the arguments.". – Luchian Grigore Jul 12 '12 at 05:48