Difference between pointer-to-pointer vs reference-to-pointer (C++)
Asked Answered
R

4

8

I have a bit of COM code that uses interface pointers. The original author of the code implemented functions that return an interface pointer like this:

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject* &pEnumerator ); // (1)

instead of the traditional

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject** ppEnumerator ); // (2)

The function (1) is called like this:

hRes = Query ( sQuery, pEnumerator ); // (3)

which definitely looks wrong but it works fine. I'm not sure if I'm just picking up this line because the out parameter is not a pointer to the output variable or because there's something wrong with this approach.

Is there an advantage to using a reference-to-pointer instead of a pointer-to-pointer for out parameters?

Radbun answered 7/12, 2011 at 23:27 Comment(3)
You should understand the difference between T*and T&, then just understand T can be a pointer-type.Satirist
¤ The reference cannot be a null-reference in a valid program. So it guards against incorrect usage, and assuming C++ usage only simplifies the implementation. However, while COM was designed with C++ usage in mind (the memory layout of a COM object is directly what early Visual C++ produced), COM was and is language independent. And so when that method is consumed in C, the pointer-to-pointer underneath, is revealed, and a C client might easily pass a nullpointer. And so if other language usage is to be supported, the reference doesn't simplify. But it's still more clear. Cheers & hth.,Aceous
Uhm, sorry for messing up answers-in-queue by fixing the title and last para, which originally said "pointer-to-reference".Aceous
S
8

The first example is that of a reference to a pointer, ie. a reference to a type IEnumWbemClassObject*:

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject* &pEnumerator );

Therefore if pEnumerator is declared as a IEnumWbemClassObject* (which I'm assuming it is), you don't need to explicitly pass the address of pEnumerator to the function or dereference the variable inside the function in order to change where pEnumerator points (which would otherwise be required with an argument of IEnumWbemClassObject**).

A reference to a pointer has the same behaviour as a reference to any other type, just think of the above example as being a "reference to a pointer" and not a "pointer to a reference." There's no such thing as a pointer to a reference.

Should answered 7/12, 2011 at 23:33 Comment(1)
Thanks a lot for the detailed explanation. Although all answers said pretty much the same thing, this one has the most detail. Thanks to all others as well for their explanations: I guess my dislike for the *& vs ** simply comes from tradition and preference.Radbun
H
5

The advantages are the same as any use of references instead of pointers:

  • simplicity
  • references can't be null, so assigning to a reference in Query won't cause an access violation

Note the original description was in error: IEnumWbemClassObject* & is a reference to a pointer, not a pointer to a reference.

Hammy answered 7/12, 2011 at 23:32 Comment(0)
O
2

It's better to think of Type& foo* as a reference to a pointer rather than the other way around, as it no longer implies that you can modify the reference through the pointer and other such C++-breaking ideas. It also makes that function call a little easier to believe in as it's just like passing anything else in by reference, no dereferencing or special symbols are required.

Oribel answered 7/12, 2011 at 23:31 Comment(0)
S
1

Its because pointer and reference are represented identically in normal c++ implementation (this is implementation detail however, not part of the standart. also its reference to pointer, not pointer to reference, you are not allowed to create pointer to reference at all.

Schema answered 7/12, 2011 at 23:31 Comment(1)
Ah ok - I didn't know that creating a pointer to a reference is not allowed.Radbun

© 2022 - 2024 — McMap. All rights reserved.