Introduction #
C++ developers are familiar with the standard set of constructors and special member functions. However, in real projects, it’s common to encounter duplicate code when handling overloaded constructors or when writing constructors for derived classes.
Code duplication makes programs harder to maintain and read. Fortunately, modern C++ provides solutions: delegating constructors and inheriting constructors. This article explains both concepts with examples.
Delegating Constructors #
A delegating constructor is a constructor that calls another constructor within the same class.
This eliminates duplication when multiple constructors need to initialize the same members.
Example: Delegating Constructors in C++ #
#include <iostream>
class Example {
public:
Example() : Example(0) {} // Delegates to another constructor
Example(int d) : data_(d), len_(10), height_(10) {}
Example(const Example &ex) : Example(ex.data_) {}
~Example() {}
void Display() {
std::cout << "data_, len_, height_: "
<< data_ << ", " << len_ << ", " << height_
<< std::endl;
}
private:
int data_;
int len_;
int height_;
};
int main() {
Example ex;
ex.Display();
Example ex1(ex);
ex1.Display();
return 0;
}
In this code:
Example()
delegates initialization toExample(int d)
.- The copy constructor also delegates to avoid repeating initialization logic.
- Passing by reference in the copy constructor prevents recursive calls and improves efficiency.
Inheriting Constructors #
When creating a derived class, constructors often look repetitive because they simply forward arguments to the base class.
With C++11, inheriting constructors make this easier by automatically reusing base class constructors in the derived class.
Example: Inheriting Constructors in C++ #
#include <iostream>
class Base {
public:
Base() : data_(3) {}
Base(int d) : data_(d), len_(10), height_(10) {}
Base(int d, int l, int h) : data_(d), len_(l), height_(h) {}
void Display(int d) { std::cout << "Value: " << d << std::endl; }
void Display(int d1, int d2) { std::cout << "Sum: " << d1 + d2 << std::endl; }
protected:
int data_;
int len_;
int height_;
};
class Derived : public Base {
public:
using Base::Base; // Inherit all constructors
using Base::Display; // Make base Display functions visible
void Display() {
std::cout << "data_, len_, height_: "
<< data_ << ", " << len_ << ", " << height_
<< std::endl;
}
};
int main() {
Derived d(2, 3, 6); // Uses Base constructor
d.Display(); // Calls Derived’s version
d.Display(2); // Calls Base::Display(int)
d.Display(2, 3); // Calls Base::Display(int, int)
return 0;
}
Here:
using Base::Base;
brings all base constructors intoDerived
.using Base::Display;
exposes overloaded base functions that would otherwise be hidden.- Note: in multiple inheritance, inheriting constructors cannot be used and you must define them manually.
Delegating vs Inheriting Constructors: Quick Comparison #
Feature | Delegating Constructors | Inheriting Constructors |
---|---|---|
Introduced in | C++11 | C++11 |
Where it applies | Within a single class | Between base and derived classes |
Purpose | Avoid duplicate initialization in overloaded constructors | Avoid rewriting base constructors in derived classes |
How it works | One constructor calls another constructor of the same class | Derived class automatically reuses base constructors |
Syntax | Class() : Class(args) {} |
using Base::Base; |
Main benefit | Centralizes initialization logic | Reduces boilerplate in inheritance hierarchies |
Limitations | Only applies within the same class | Cannot be used with multiple inheritance |
Conclusion #
C++ evolves to make code simpler and more natural.
- Delegating constructors reduce duplication inside a class.
- Inheriting constructors eliminate repetitive boilerplate in derived classes.
Both features improve code readability and maintainability, helping developers focus on logic instead of redundancy.