Files
2025-10-25 03:02:53 +03:00

4.0 KiB

[class.inhctor.init]

11 Classes [class]

11.9 Initialization [class.init]

11.9.4 Initialization by inherited constructor [class.inhctor.init]

1

#

When a constructor for type B is invoked to initialize an object of a different type D (that is, when the constructor was inherited ([namespace.udecl])), initialization proceeds as if a defaulted default constructor were used to initialize the D object and each base class subobject from which the constructor was inherited, except that the B subobject is initialized by the inherited constructor if the base class subobject were to be initialized as part of the D object ([class.base.init]).

The invocation of the inherited constructor, including the evaluation of any arguments, is omitted if the B subobject is not to be initialized as part of the D object.

The complete initialization is considered to be a single function call; in particular, unless omitted, the initialization of the inherited constructor's parameters is sequenced before the initialization of any part of the D object.

[Example 1: struct B1 { B1(int, ...) { }};

struct B2 { B2(double) { }};

int get();

struct D1 : B1 {using B1::B1; // inherits B1(int, ...)int x; int y = get();};

void test() { D1 d(2, 3, 4); // OK, B1 is initialized by calling B1(2, 3, 4),// then d.x is default-initialized (no initialization is performed),// then d.y is initialized by calling get() D1 e; // error: D1 has no default constructor}struct D2 : B2 {using B2::B2; B1 b;};

D2 f(1.0); // error: B1 has no default constructorstruct W { W(int); };struct X : virtual W { using W::W; X() = delete; };struct Y : X { using X::X; };struct Z : Y, virtual W { using Y::Y; }; Z z(0); // OK, initialization of Y does not invoke default constructor of Xtemplate struct Log : T {using T::T; // inherits all constructors from class T~Log() { std::clog << "Destroying wrapper" << std::endl; }};

Class template Log wraps any class and forwards all of its constructors, while writing a message to the standard log whenever an object of class Log is destroyed.

— end example]

[Example 2: struct V { V() = default; V(int); };struct Q { Q(); };struct A : virtual V, Q {using V::V; A() = delete;};int bar() { return 42; }struct B : A { B() : A(bar()) {} // OK};struct C : B {};void foo() { C c; } // bar is not invoked, because the V subobject is not initialized as part of B — end example]

2

#

If the constructor was inherited from multiple base class subobjects of type B, the program is ill-formed.

[Example 3: struct A { A(int); };struct B : A { using A::A; };

struct C1 : B { using B::B; };struct C2 : B { using B::B; };

struct D1 : C1, C2 {using C1::C1; using C2::C2;};

struct V1 : virtual B { using B::B; };struct V2 : virtual B { using B::B; };

struct D2 : V1, V2 {using V1::V1; using V2::V2;};

D1 d1(0); // error: ambiguous D2 d2(0); // OK, initializes virtual B base class, which initializes the A base class// then initializes the V1 and V2 base classes as if by a defaulted default constructorstruct M { M(); M(int); };struct N : M { using M::M; };struct O : M {};struct P : N, O { using N::N; using O::O; }; P p(0); // OK, use M(0) to initialize N's base class,// use M() to initialize O's base class — end example]

3

#

When an object is initialized by an inherited constructor, initialization of the object is complete when the initialization of all subobjects is complete.