Overloading
Syntactically, an initialization list that contains a delegated constructor looks exactly like a C++98 member initialization list. So how can the compiler (and you) tell them apart? Consider:
class A
{
public:
explicit A(int);
};
class B: public A
{
public:
explicit B(int n) : A(n) {} //C++98 mem-init
B() : B(0) {}//delegating ctor
};
There's no confusion between the two because a target constructor always has the same name as its delegating constructors.
When you have multiple constructors with the same name, the standard overload resolution rules determine which target constructor will be used:
struct X
{
explicit X(int) {} #1
explicit X(bool) {} #2
X() : X(true) {} #3 calls #2
explicit X(int *p) : X(*p) {} #4 calls #1
};
The delegating constructor
#3 invokes the target constructor
#2 because the argument
true is of type
bool. Similarly, the delegating constructor
#4 invokes the target constructor
#1 because
*p is
int.
Best of Both Worlds
Delegating constructors eliminate code reduplication in constructors while still ensuring that the common initialization steps are performed during the object's initialization. This has three advantages:
- Reference and const members can be initialized in once place.
- Other member functions can't invoke the target constructor accidentally.
- The target constructor always runs once, before the delegating constructor's body.
In April 2006, the
delegating constructors proposal was integrated into the current Working Paper of the C++ standard. This means that the next C++ standard (due in 2009) will support this feature. You won't have to wait that long for this feature, though. Vendors will probably start supporting it sooner, once the Final Candidate Document (due at the end of 2007) is published.