views:

587

answers:

9

I wrote a function along the lines of this:

void myFunc(myStruct *&out) {
    out = new myStruct;
    out->field1 = 1;
    out->field2 = 2;
}

Now in a calling function, I might write something like this:

myStruct *data;
myFunc(data);

which will fill all the fields in data. If I omit the '&' in the declaration, this will not work. (Or rather, it will work only locally in the function but won't change anything in the caller)

Could someone explain to me what this '*&' actually does? It looks weird and I just can't make much sense of it.

+16  A: 

The & symbol in a C++ variable declaration means it's a reference.

It happens to be a reference to a pointer, which explains the semantics you're seeing; the called function can change the pointer in the calling context, since it has a reference to it.

unwind
sbi
@sbi: Agreed, I changed it ... Now it's maybe a bit self-referential though.
unwind
Better now, I hope. :) A bit academic, since Adriaan's answer has been accepted.
unwind
@unwind: I think it's a darn good idea to improve on the answer that's up-voted the most, even when the OP has abandoned the question. SO is searchable, after all, and the next programmer stumbling over this will appreciate your answer nevertheless.
sbi
@sbi: I agree, of course. I'd rather be correct than accepted.
unwind
+1  A: 

See wikipedia

qrdl
+1  A: 

In C++ it's a reference to a pointer, sort of equivalent to a pointer to pointer in C, so the argument of the function is assignable.

Nikolai N Fetissov
+8  A: 

In C and C++, & means call by reference; you allow the function to change the variable. In this case your variable is a pointer to myStruct type. In this case the function allocates a new memory block and assigns this to your pointer 'data'.

In the past (say K&R) this had to be done by passing a pointer, in this case a pointer-to-pointer or **. The reference operator allows for more readable code, and stronger type checking.

Adriaan
A: 

MyClass *&MyObject

Here MyObject is reference to a pointer of MyClass. So calling myFunction(MyClass *&MyObject) is call by reference, we can change MyObject which is reference to a pointer. But If we do myFunction( MyClass *MyObject) we can't change MyObject because it is call by value, It will just copy address into a temporary variable so we can change value where MyObject is Pointing but not of MyObject.

so in this case writer is first assigning a new value to out thats why call by reference is necessary.

GG
+4  A: 

This looks like you are re-implementing a constructor!

Why not just create the appropriate constructor?
Note in C++ a struct is just like a class (it can have a constructor).

struct myStruct
{
    myStruct()
        :field1(1)
        ,field2(2)
    {}
};

myStruct*  data1 = new myStruct;

// or Preferably use a smart pointer
std::auto_ptr<myStruct>   data2(new myStruct);

// or a normal object
myStruct    data3;
Martin York
Indeed, I was re-implementing a constructor. Thank you for the tip!
BastiBechtold
I may not have answered the question you asked. But I gave you the answer to the question you should have asked. That's worth another vote.
Martin York
+1  A: 

As with most data types in C++, you can read it right-to-left and it'll make sense.

myStruct *&out

out is a reference (&) to a pointer (*) to a myStruct object. It must be a reference because you want to change what out points at (in this case, a new myStruct).

Kristo
+3  A: 

It may be worthwhile to explain why it's not &*, but the other way around. The reason is, the declarations are built recursively, and so a reference to a pointer builds up like

& out // reference to ...
* (& out) // reference to pointer

The parentheses are dropped since they are redundant, but they may help you see the pattern. (To see why they are redundant, imagine how the thing looks in expressions, and you will notice that first the address is taken, and then dereferenced - that's the order we want and that the parentheses won't change). If you change the order, you would get

* out // pointer to ...
& (* out) // pointer to reference

Pointer to reference isn't legal. That's why the order is *&, which means "reference to pointer".

Johannes Schaub - litb
+1  A: 

Like others have said, the & means you're taking a reference to the actual variable into the function as opposed to a copy of it. This means any modifications made to the variable in the function affect the original variable. This can get especially confusing when you're passing a pointer, which is already a reference to something else. In the case that your function signature looked like this

void myFunc(myStruct *out);

What would happen is that your function would be passed a copy of the pointer to work with. That means the pointer would point at the same thing, but would be a different variable. Here, any modifications made to *out (ie what out points at) would be permanent, but changes made to out (the pointer itself) would only apply inside of myFunc. With the signature like this

void myFunc(myStruct *&out);

You're declaring that the function will take a reference to the original pointer. Now any changes made to the pointer variable out will affect the original pointer that was passed in.

That being said, the line

out = new myStruct;

is modifying the pointer variable out and not *out. Whatever out used to point at is still alive and well, but now a new instance of myStruct has been created on the heap, and out has been modified to point at it.

Graphics Noob