IntroductionWhy We Need Them?Syntax of Pointer to PointerSyntax of Reference to PointerSyntax of tracking reference to a handle(C++/CLI)(new)Preference of one over the other?Do not Mistake Pointer to Pointer argumentsReference to Pointer type (RTTI)What Are Other Alternatives?ConclusionHistory
This article explains the reason behind using pointer-to-pointer and reference-to-pointer to modify a pointer passed to a function, so as to understand their usage better. For brevity, I use the terms, ptr-to-ptr and ref-to-ptr to represent them respectively. In this article, I'm not going to discuss how to use ptr-to-ptr as a 2 dimensional array or array of pointers. Please note we can use ptr-to-ptr in both C and C++ but we can use ref-to-ptr only in C++.
Why We Need Them?
When we use "pass by pointer" to pass a pointer to a function, only a copy of the pointer is passed to the function. We can say "pass by pointer" is passing a pointer by value. In most cases, this does not present a problem. But problem comes when you modify the pointer inside the function. Instead of modifying the variable, you are only modifying a copy of the pointer and the original pointer remains unmodified, that is, it still points to the old variable. The code below demonstrates this behavior.
void func(int* pInt);
void func(int* pInt)
Syntax of Pointer to Pointer
This is how you called the function with ptr-to-ptr parameter.
void func(int** ppInt);
Let us see how it to modify the ptr-to-ptr in the function.
void func(int** ppInt)
Let me surmarise what all those dereferencing are,
ppInt is the ptr-to-ptr. We will never modify this because if we do, we'll lose our grip on the address of the pointer it is pointing to.
*ppInt is the pointed pointer. If we modify this, we are modifying the contents of the pointed pointer, which is an address and in the above example,
pvar. In other words, we are effectively modifying what
pvar points to.
**ppInt is the dereferenced twice variable which is what
pvar points to.
Syntax of Reference to Pointer
Now let us look at how you call the function with ref-to-ptr parameter
void func(int*& rpInt);
Let us see how it to modify the ref-to-ptr in the function.
void func(int*& rpInt)
You may wonder whether, in the above
func(), the parameter
rpInt is pointer to reference. Just take my word for it that it is called ref-to-ptr and it is ref-to-ptr.
Let me once again summarize what all those dereferencing are,
rpInt is the reference for the pointer,
pvar in the above example.
*rpInt dereferences what
pvar point to, so you get the variable the pointer,
pvar is pointing to.
Syntax of Tracking Reference to a Handle(C++/CLI)
Let us see how to modify a handle in C++/CLI function using the "tracking reference to a handle" parameter. This C++/CLI handle has nothing to do with Win32 HANDLEs and this handle is a reference to a managed object on the CLI heap. I use an object this time, instead of a Plain Old Data(POD)/primitive data/value type because you can only change a reference to an object.
void func(ClassA^% thObj);
ClassA^ obj = gcnew ClassA;
void func(ClassA^% thObj)
thObj=g_obj; thObj=gcnew ClassA();
thObj is the tracking reference for the handle, obj2 in the above example.
Preference of one over the other?
Now we have seen the syntax of ptr-to-ptr and ref-to-ptr. Are there any advantages of one over the other? I am afraid, no. The usage of one of both, for some programmers are just personal preferences. Some who use ref-to-ptr say the syntax is "cleaner" while some who use ptr-to-ptr, say ptr-to-ptr syntax makes it clearer to those reading what you are doing.
Do not Mistake Pointer to Pointer Arguments
Do not mistake every ptr-to-ptr arguments as purely ptr-to-ptr. An example would be when some write
int main(int argc, char *argv) as
int main(int argc, char **argv) where
**argv is actually an array of pointers. Be sure to check out the library documentation first!
Reference to Pointer type (RTTI)
You cannot use RTTI to find out the type of ref-to-ptr. As
typeid() does not support reference types.
void test(int*& rpInt)
std::cout << "type of *&rpInt: " << typeid(rpInt).name()
What are other alternatives?
If you find that the ptr-to-ptr and ref-to-ptr syntax are rather hard to understand, you can just use the "return the pointer" method.
ClassA* p = new ClassA();
You may ask if you would ever use ptr-to-ptr and ref-to-ptr in your projects and if it is necessary to know about them. Well, as developers, we use libraries and technologies developed by others. One example would be COM uses ptr-to-ptr to return an interface pointer using
IUnknown::QueryInterface(). Up to some point in your developer career, you are definitely going to come across them. It is good to know them.
- 2009/04/29 Updated the explanations and added tracking reference to a handle in C++/CLI section.
- 2003/09/01 First release