Lets say I have a class "A" and this function:
void initializationFunction(A* classPointer)
{
...
...
classPointer = new A(.....);
}
I write:
A* classPointer;
Then I pass this pointer to this fun开发者_开发技巧ction:
initializationFunction(classPointer);
This will not work unless I pass it by reference in the function declaration:
void initializationFunction(A*& classPointer);
I thought reference passing was for non-pointer type variables. I mean you don't need to pass an array by reference...
Thanks for the explanations :)
Yeah, that is true. You've to pass the argument by reference (or you can pass A**
instead).
But the best solution is to write the constructor of A
in such way that you wouldn't need this function in the first place. That is, whatever you're doing in this function, you should be doing that in the constructor itself.
If, however, you cannot edit the class, then you can do this instead:
A *initializationFunction()
{
A *obj = new A(.....);
//...
return obj;
}
A *classPointer = initializationFunction();
In my opinion, this approach is better than yours.
Note I didn't change the name of the function and other variables. I guess that isn't the point of the post. But I believe you would want better names for real code.
Either you declaration with the reference or the following one will do:
void initializationFunction(A** classPointer);
The point is that you are passing in a pointer argument and that you want to modify the value it had in the caller. This is an out parameter and out parameters should be passed by reference, not by value (reference here means either through a pointer or reference). This out parameter is a pointer, so you should pass a pointer to that pointer or a reference to that pointer.
In other words, you need to access the original argument in the caller stack to be able modify it. In the declaration
void initializationFunction(A* classPointer);
classPointer
is akin to a local variable defined inside of initializationFunction
and is just a copy of the classPointer
you allocated in the caller function. Modifying a copy of classPointer
will not modify the original variable, so you need a pointer to the original variable to be able to modify it. The same holds true if you use a reference to the original classPointer
.
An alternative approach you have is returning the new classPointer
from your function:
A* initializationFunction(void);
in this case the caller would simply do:
A* classPointer = initializationFunction();
You can pass any variable by reference. The difference between passing by reference and passing by value, is that when you pass by reference, you are in fact passing the very same pointer that is pointing to the value in that memory location, and when you pass by value you are just passing another reference to that memory location, and therefore anything you assign to it will NOT change the value of the parameter passed.
Either use a double pointer (a**) or a reference as you did.
In your first example, the pointer is passed by value (ie. the function gets a copy of the pointer). The object that the pointer points to is of course the same both in the calling code and inside the function.
In the second example, the pointer is passed by reference (ie. the function basically uses the same pointer as the calling code).
say you had a windows shortcut pointing to a text file in "My Documents".
you can copy that shortcut and paste it anywhere in windows, double click on it, and it opens the text file in "My Documents". That is passing by reference / pointer. The shortcut points to "where", then you use it to change the "stuff".
However, the code you posted doesn't "open" the file pointed to by the shortcut. It actually changes the shortcut to point to (actually create ) a new "file". But since the shortcut itself was first copied ( passed by value ), the effect is that you allocated memory but cannot access it. So analogously you changed the shortcut, created a "file", but then deleted the directory with that shortcut in there ( but your file is then lost in outer space !).
Unfortunately, there is really no analogy for passing a shortcut itself by reference, you would basically have to copy the shortcut back out of the directory, then replace the original text file in "my documents" with a shortcut to this new "file". Hope this helps instead of confuses it further :(.
The reason you have to pass the pointer by reference is that you're actually changing where in memory it points to. If you had already assigned it to an object and wanted to modify that object, passing it directly to the function would be fine.
When you do a Aptr = new A(...)
, you are
- Creating an 'A' object somewhere on the heap
- Assigning the address of the newly created object to Aptr
If the function doesn't have a reference to Aptr
, the function can't change its value.
You can pass pointers by reference because pointers are also variables with their own address.
For example, in a 32-bit architecture, you can declare an unsigned int
and use it as a pointer.
This is normal.
I explain:
void foo(X* toto)
{
toto=new X();
}
toto value will be poped out from call stack with it's initial value (as any other argument , pointer or not) since it's not possible to change function argument value UNLESS it's a reference.
so:
void foo(X*& toto)
{
toto=new X();
}
Here you explicitely say toto argument as being X*& (X* for type , and & (reference) to let it's value be modified inside function foo)
Pointer types are the same than any other types. replace X* by int and you'll immediately find that toto won't be changed outside of function call unless passed as reference.
An X** would also have done the trick , using such implementation:
void foo(X** toto)
{
*toto=new X();
}
It should be:
void initializationFunction(A** classPointer)
{
...
...
*classPointer = new A(.....);
}
Call:
initializationFunction(&ptr);
the function will set the argument passed in to the new A(......);
example: http://ideone.com/u7z6W
精彩评论