"From One Constructor to Another": The Eternal Question of C++ Developers
\n\nImagine a situation: you are writing a class with several constructors. One takes three parameters, another takes two, a third takes one. And all of them repeat the same initialization logic. You itch to write something like MyClass() : MyClass(42, "default") {} — and forget about duplication. But the C++ compiler (until a certain point) looks at this askance. Is it even possible to call a constructor from another constructor? And if so — how?
This question is one of the most popular on Stack Overflow (tens of thousands of views). Not surprising: the topic of constructor chaining is a real stumbling block for beginners and even experienced developers transitioning to C++ from Java or Python. In this article, we will break down three approaches to solving the problem, from "crutches" to elegant C++11 solutions, and find out which one should be used in real code.
\n\nWhy Can't You Just Call a Constructor from a Constructor?
\n\nThe naive approach looks like this:
\n\nclass MyClass {\npublic:\n MyClass() {\n // some code\n }\n MyClass(int x) {\n MyClass(); // ERROR: you can't do this!\n }\n};\n\nIn C++, a constructor is not an ordinary function. It initializes an object once. If you try to explicitly call another constructor inside the body, the compiler will treat it as creating a temporary object — and nothing will be initialized in the current instance. The result: either a compilation error, or (worse) undefined behavior.
\n\nBefore the C++11 standard, the only legal way to "share" initialization logic was to call a private init() method. But this was not true delegation: the class members were first initialized by the default constructor, and then overwritten. Inefficient and bug-prone.
Approach #1: Delegating Constructors (C++11 and newer)
\n\nStarting with C++11, the language introduced a long-awaited feature — delegating constructors. Now you can call one constructor from another directly in the initializer list:
\n\nclass MyClass {\n int value;\n std::string name;\npublic:\n // Base constructor\n MyClass(int v, const std::string& n) : value(v), name(n) {\n std::cout << "Full init: " << value << ", " << name << "\\n";\n }\n // Delegating constructor\n MyClass(int v) : MyClass(v, "default") {}\n // Another delegating constructor\n MyClass() : MyClass(0, "default") {}\n};\n\nHow does it work? The constructor MyClass(int v) passes control to the constructor MyClass(int, string). That one performs all the initialization, and only then does control return back. Important rule: in the initializer list, you cannot mix calling another constructor with direct member initialization. Either delegation or your own initialization — one of the two.
Pros and Cons
\n- \n
- ✅ Elegance: the code becomes clean, without duplication. \n
- ✅ Performance: the object is initialized once, without unnecessary operations. \n
- ⚠️ Limitation: delegation only works one level "deep" — the chain cannot be recursive (you will cause a stack overflow). \n
- ⚠️ Compatibility: requires C++11 or newer. If you are stuck with an ancient compiler — this option is not for you. \n
Approach #2: Private init() Method
\n\nThe classic "pre-C++11" way is to move the common logic into a private method. It looks like this:
\n\nclass MyClass {\n int value;\n std::string name;\n void init(int v, const std::string& n) {\n value = v;\n name = n;\n std::cout << "Init called\\n";\n