0
#include <iostream>
using namespace std;

class A{
    public:
    A(){
        cout << "A ";
    }
    A(int a){
        cout << "PA ";
    }
};

class B{
    public:
    B(){
        cout << "B ";
    }
    
    B(int a){
        cout << "PB ";
    }
};

class C: public A, public B {
    public:
    C():B(),A(){
        cout << "C ";
    }
};

int main()
{
    C();
    return 0;
}

Output:

A B C

Because class C constructor is specified as C():B(),A() (according to the class C constructor initializer list), the order of the base class constructors should be B before A. However, the base class constructor is only called in the order of inheritance in code output. Can somebody explain this behavior to me?

Hardik
  • 149
  • 6
  • 1
    Please see ["Initialization Order"](https://en.cppreference.com/w/cpp/language/constructor#Initialization_order). – G.M. Aug 12 '23 at 10:15
  • 1
    Enable warnings in your compiler. They _will_ tell you why that is happening. – user17732522 Aug 12 '23 at 10:21
  • Destruction is in the reverse order of construction (a slight over-simplification). If you were able to choose the order in which sub-objects are constructed then the compiler would have to add code to ensure that those sub-objects are destroyed in the reverse order. That's a cost for no clear benefit, so it's disallowed. – john Aug 12 '23 at 11:23
  • *the order of the base class constructors should be `B` before `A`* - What makes you think so? Do you know any particular language rule for that? – Evg Aug 12 '23 at 12:20

1 Answers1

2

The order of subobject initialization is not the same as the order of initializers in a base-member initialization list. What matters is the order of objects within the class. The objects which appear first are initialized first, no matter what order is used on the base-member initialization list.

See the section entitled Initialization order at CppReference.

The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:

  1. If the constructor is for the most-derived class, virtual bases are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists).
  2. Then, direct bases are initialized in left-to-right order as they appear in this class's base-specifier list.
  3. Then, non-static data member are initialized in order of declaration in the class definition.
  4. Finally, the body of the constructor is executed.

(Note: if initialization order was controlled by the appearance in the member initializer lists of different constructors, then the destructor wouldn't be able to ensure that the order of destruction is the reverse of the order of construction.)

tbxfreeware
  • 547
  • 1
  • 9