Reputation: 17189
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.
Upvotes: 27
Views: 81616
Reputation: 10050
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.
Upvotes: 4
Reputation: 399813
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.
So, to reiterate, the "operative symbol" here is not *&
, that combination in itself doesn't mean a whole lot. The *
is part of the type myStruct *
, i.e. "pointer to myStruct
", and the &
makes it a reference, so you'd read it as "out
is a reference to a pointer to myStruct
".
The original programmer could have helped, in my opinion, by writing it as:
void myFunc(myStruct * &out)
or even (not my personal style, but of course still valid):
void myFunc(myStruct* &out)
Of course, there are many other opinions about style. :)
Upvotes: 45
Reputation: 3312
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.
Upvotes: 14
Reputation: 506955
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".
Upvotes: 9
Reputation: 35188
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
).
Upvotes: 2
Reputation: 264391
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;
Upvotes: 6
Reputation: 2951
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.
Upvotes: 1
Reputation: 84159
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.
Upvotes: 3