rmadhwal rmadhwal - 1 month ago 7
C++ Question

Why is it ok to satisfy an explicit constructor's argument using member initialisation in a constructor?

I'm sorry for the incredibly cryptic title.

I have been reading "More Exceptional C++" by Herb Sutter, and I came across an example of a "counted pointer", I won't paste the entire code, but he uses an explicit constructor with the signature:

explicit countedPointer(P* obj): p(new impl(obj) ) {}


Further, he declares a class which has a counted Pointer object as a private member of the class, in the constructor of this class, he initialises his counted pointer as so:

flagNth(n):pimpl_(new flagNthImpl(n)) {}


where, pimpl_ is the counter pointer object, i.e.

countedPointer<flagNthImpl>pimpl_;


I tried to run this code and inside main.cpp, if I try to do the following I get an error (obviously, since the constructor is explicit)

int main(int argc, const char * argv[])
{
countedPointer<int> cp = new int(5);
}


My question is, why is it ok to do this inside the member initialisation list of a constructor instead ? Is the initialisation somehow different from a regular initialisation, and if so, how ?

Thank you!

Answer

This would work for you in main:

countedPointer<int> cp(new int(5));

It's direct initialisation and would invoke the constructor normally.

However, you're doing this:

countedPointer<int> cp = new int(5);

That's copy initialisation, and that doesn't work with explicit constructors. To successfully use copy initialisation with an explicit constructor, you'd need this:

countedPointer<int> cp = countedPointer<int>(new int(5));

Of course, you're generally better off using direct initialisation (as the first example), or direct list initialisation:

countedPointer<int> cp{new int(5)};