Browse DevX
Sign up for e-mail newsletters from DevX


Use C++0x's Inheriting Constructors to Reduce Boilerplate Code in Class Hierarchies-3 : Page 3

A base class with multiple constructors forces a derived class to define corresponding constructors that merely forward their arguments to the matching base constructor. In C++03, you define the derived class's constructors manually. Learn how C++0x's inheriting constructors feature automates this process, thereby simplifying code maintenance and making your code more readable and secure.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Overriding Inheriting Constructors

As always, you can still add new constructors to a derived class, even one that uses inheriting constructors. If a user-declared constructor and an implicitly declared inheriting constructor have the same signature, the user-declared constructor takes precedence—effectively hiding the inheriting constructor with the same signature. Here's an example:

struct D1 : A1 { using A1::A1;//explicit D1(int); explicit D1( double); //a user-defined ctor hides the inherited ctor D1(int) explicit D1(int j): A1(0), x(j) {} private: int x; }; D1 d4(0); //OK, invokes D1(int n): A1(0),x(n) {}

Handling Multiple Inheritance

When a derived class has two or more immediate base classes, you can selectively state which base class's constructors to inherit using this syntax:

struct B1 { B1(char); }; struct B2 { B2(double); B2(int); }; struct D1 : B1, B2 { using B1::B1; // D1(char) using B2::B2; // D1(double), D1(int) }; D1 d('c'); //OK, invokes D1(char)

In certain cases, multiple inheritance can lead to ambiguity. Suppose you have two base classes that declare constructors with identical signatures. Inheriting these constructors will cause an error:

struct C1 { C1(int); C1(double); }; struct C2 { C2(int); }; struct D1 : C1, C2 { using C1::C1; // D1(int), D1(double) using C2::C2; // D1(int) //conflicts with D(int) above }; D1 d(5); //error, should this call C1(1) or C2(1)?

In this situation, because a user-declared constructor supersedes any implicit constructor declaration with the same signature, you can avoid the ambiguity by declaring the problematic constructor explicitly:

struct C1 { C1(int); C1(double); }; struct C2 { C2(int); }; struct D1 : C1, C2 { using C1::C1; // D1(int), D1(double) using C2::C2; // D1(int) D1(int n): C1(n), C2(n), x(n) {} //override D(int) private: int x; }; D1 d(5); //OK, calling user-defined ctor

Status and Support

Do not confuse inheriting constructors with delegating constructors; the latter apply only to constructors within the same class. The inheriting constructors proposal has already been voted into the C++0x Working Draft, so compiler vendors should start supporting this feature soon.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Thanks for your registration, follow us on our social networks to keep up-to-date