Login | Register   
RSS Feed
Download our iPhone app
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.


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++."
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date