views:

157

answers:

7

I have a method:

odp(foo& bar);

I'm trying to call it:

foo baz;
odp(&baz);

I get a compiler error:

error C2664: "odp" cannot convert parameter 1 from 'foo *' to 'foo &'

What am I doing wrong? Aren't I passing in a reference to baz?

UPDATE: Perhaps I have a misconception about the relationship between pointers and references. I thought that they were the same, except references couldn't be null. Is that incorrect?

+4  A: 

The odp function need a reference to a foo var whereas you are passing the adress of a foo var (pointer).

Just pass baz like:

foo baz;
opd(baz);

And it will compile.

Patrice Bernassola
mm... I thought that doing what would actually copy `baz` onto the stack, so if I make changes to `baz`, they won't be seen by the caller?
Rosarch
Any changes to baz will be seen by the caller this way.
PeterK
No you are passing the reference to the var so it will work as you want. ANy modification of baz into odp() will be seend after returning from odp().
Patrice Bernassola
el.pescado
JSBangs
+2  A: 

No, you're passing a pointer to baz. Drop the &.

JSBangs
+2  A: 

When you use &baz, you are actually saying address of baz, so you are passing a pointer.

KevinH
+5  A: 

When you apply the unary & operator to an object, you get a pointer to that object, not a reference. You need a reference in this case. In order to initialize a reference parameter, you don't need to apply any operators at all: an lvalue object can immediately be used by itself to initialize a reference of the appropriate type.

The informal synonymity between the notions of "pointer" and "reference" (as in "pass by pointer" and "pass by reference") is specific to C language. But in C++ they mean two completely different things.

AndreyT
Could you elaborate further on the difference between pointers and references?
Rosarch
@Rosarch: They are two different things. Drop what you think you know about them, there's your difference. References are aliases to variables, pointers are addresses of variables, they are different. A reference can't be "null" because you can't alias a non-existent variable.
GMan
The critical point here is that, "references are _aliases_ to variables." They are not pointers to variables.
Andres Jaan Tack
A: 

Maybe you're being misled by old C conventions? In C, you "pass by reference" by creating a pointer, because the language doesn't have references - you use the pointer to "reference" the original variable. In C++, references are supported by the language and there's no need to create a pointer to the variable when you call the function.

foo baz; 
odp(baz); 
Mark Ransom
+1  A: 

References and pointers are NOT the same in C++ - although you have probably read that most compilers implement references using pointers at the machine-code level. You don't need to care how they are implemented by the compiler - but what the semantics of a "reference" and a "pointer" are in C++.

int i = 5;
int &j = i;  // j refers to the variable i
// wherever the code uses j, it actually uses i
j++;  // I just changed i from 5 to 6
int *pj = &i;  // pj is a pointer to i
(*pj)--;  // I just changed i back to 5

Note that I can change pj to point to another integer, but I cannot change the reference j to refer to another integer.

int k = 10;
pj = &k;  // pj now actually points to k
(*pj)++;  // I just changed k to 11
j = k;  // no, this doesn't change the reference j to refer to k instead of i,
// but this statement just assigned k to i, that is, i now equals 11!
franji1
+1  A: 

In C++, references are aliases, not addresses. You can, for instance, have multiple names for a single pointer, just as you might have multiple names for a single real object.

When you declare a function taking a reference parameter, the function will automatically alias whatever variable you pass to it. Whatever it aliases, though, must be of the same type as the reference. In your case, you are aliasing an int* with an int reference, which doesn't make sense.

Andres Jaan Tack