Delegating constructors (C++0x)

Note: C++0x is a new version of the C++ programming language standard. This is a draft standard and has not been officially adopted in its entirety. The implementation of C++0x is based on IBM's interpretation of the draft C++0x standard and is subject to change at any time without notice. IBM makes no attempt to maintain compatibility with earlier releases and therefore the C++0x language extension should not be relied on as a stable programming interface.

Before C++0x, common initializations in multiple constructors of the same class could not be concentrated in one place in a robust, maintainable manner. To partially alleviate this problem in the existing C++ programs, you could use assignment instead of initialization or add a common initialization function.

With the delegating constructors feature, you can concentrate common initializations and post initializations in one constructor named target constructor. Delegating constructors can call the target constructor to do the initialization. A delegating constructor can also be used as the target constructor of one or more delegating constructors. You can use this feature to make programs more readable and maintainable.

Delegating constructors and target constructors present the same interface as other constructors. Target constructors do not need special handling to become the target of a delegating constructor. They are selected by overload resolution or template argument deduction. After the target constructor completes execution, the delegating constructor gets controls back.

In the following example, A(T) and A(U) both delegate to A(T,U). This example demonstrates a typical usage of placing common initializations in a single constructor.
#include <cstdio>
template <typename T, typename U> struct A{
  const T t;
  const U u;

  static T tdef;
  static U udef;

  A(T t_, U u_): t(t_^u_), u(u_){}
  A(T t_):A(t_, udef){}
  A(U u_):A(tdef,u_){}
};

template <typename T, typename U> 
T A<T,U>::tdef;

template <typename T, typename U>
U A<T,U>::udef;

int main(void){
  A<unsigned char, unsigned>::tdef = 42u & 0x0F;
  A<unsigned char, unsigned> a(42u & 0xF0);
  std::printf("%d\n", a.t);
  return 0;
}
The output of the example is:
42
In the example, A(T) and A(U) are delegating constructors, A(T,U) is the target constructor. The constant non-static data member t is initialized with an expression involving two parameters and the operator ^ in the non-delegating constructor.
A delegating constructor can be a target constructor of another delegating constructor, thus forming a delegating chain. The first constructor invoked in the construction of an object is called principal constructor. A constructor cannot delegate to itself directly or indirectly. The compiler can detect this violation if the constructors involved in a recursive chain of delegation are all defined in one translation unit. Consider the following example:
struct A{
  int x,y;
  A():A(42){}
  A(int x_):A() {x = x_;}
};
In the example, there is an infinitely recursive cycle that constructor A() delegates to constructor A(int x_), and A(int x_) also delegates to A(). The compiler issues an error to indicate the violation.
You can use the delegating constructors feature interacting with other existing techniques:
  • When several constructors have the same name, name and overload resolution can determine which constructor is the target constructor.
  • When using delegating constructors in a template class, the deduction of template parameters works normally.