Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A delegating constructor in C++ allows one constructor to invoke another constructor within the same class to handle object initialization. Introduced in C++11, this mechanism enables a constructor (the delegating constructor) to forward the initialization responsibility to a peer constructor (the target constructor) strictly through the member initializer list.

Syntax

Delegation is achieved by calling the target constructor in the member initializer list of the delegating constructor.
class Widget {
    int width;
    int height;

public:
    // Target Constructor
    Widget(int w, int h) : width(w), height(h) {
        // Target body executes first
    }

    // Delegating Constructor
    Widget(int size) : Widget(size, size) {
        // Delegating body executes second
    }

    // Delegating Constructor (Default)
    Widget() : Widget(10) {
        // Delegating body executes third
    }
};

Execution Sequence

When a delegating constructor is invoked, the execution follows a strict, deterministic order:
  1. The arguments for the target constructor are evaluated.
  2. The target constructor’s member initializer list executes.
  3. The target constructor’s body executes to completion.
  4. The delegating constructor’s body executes.
If a chain of delegation exists (e.g., Constructor A delegates to B, which delegates to C), the target constructor at the end of the chain (C) completes its initialization and body execution first, followed by the intermediate bodies (B), and finally the initial caller’s body (A).

Technical Constraints and Rules

1. Mutually Exclusive Initialization If a constructor delegates to another constructor, its member initializer list cannot contain any other initializers. The delegation must be the sole entry in the list. Attempting to initialize a member variable alongside a delegation results in a compilation error.
class Widget {
    int width;
    int height;

public:
    Widget(int w, int h) : width(w), height(h) {}

    // ERROR: Cannot delegate and initialize 'height' simultaneously
    Widget(int w) : Widget(w, 10), height(20) {} 
};
2. Exception Handling Exception handling in delegating constructors introduces a critical distinction regarding object destruction:
  • If the target constructor throws: The exception propagates to the caller, and the delegating constructor’s body does not execute. If the exception occurs during the target constructor’s execution (e.g., a member’s constructor throws), only the members and base classes successfully constructed prior to the exception will have their destructors invoked during stack unwinding.
  • If the delegating constructor throws: Because the object’s lifetime officially begins the moment the target constructor finishes execution, the object is considered fully constructed. If the delegating constructor’s body subsequently throws an exception, the destructor for the fully-constructed object will be invoked. This is a major behavioral difference from standard constructors, where throwing an exception prevents the object’s destructor from running.
3. Delegation Cycles Circular delegation, where a set of constructors delegate to each other forming an infinite loop, is ill-formed. Modern C++ compilers will detect this and issue a compilation error.
class Widget {
public:
    // ERROR: Delegation cycle
    Widget(int x) : Widget(x, 0) {}
    Widget(int x, int y) : Widget(x) {} 
};
4. Object Lifetime The object is considered fully constructed and its lifetime begins the moment the target constructor finishes execution, not when the delegating constructor finishes. This means virtual function calls and this pointer usage within the delegating constructor’s body operate on a fully initialized object.
Master C++ with Deep Grasping Methodology!Learn More