Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Construction and initialization order guarantees

I have some doubts about construction and initialization order guarantees in C++. For instance, the following code has four classes X, Y, Z and W. The main function instantiates an object of class X, which contains an object of class Y, and derives from class Z, so both constructors will be called. Additionally, the const char* parameter passed to X's constructor will be implicitly converted to an object of class W, so W's constructor must also be called.

What are the guarantees the C++ standard gives on the order of the calls to the copy constructors? Or, equivalently, what this program is allowed to print?

#include <iostream>

class Z {
   public:
   Z() { std::cout << "Z" << std::endl; }
};

class Y {
   public:
   Y() { std::cout << "Y" << std::endl; }
};

class W {
   public:
   W(const char*) { std::cout << "W" << std::endl; }
};

class X : public Z {
   public:
   X(const W&) { std::cout << "X" << std::endl; }
   private:
   Y y;
};

int main(int, char*[]) {
   X x("x");
   return 0;
}

edit: Is this correct?

   W      |
 /   \    |
Z     Y   |
 \   /    |
   X      V
like image 909
Giovanni Funchal Avatar asked Mar 25 '10 15:03

Giovanni Funchal


People also ask

What is the named constructor idiom?

[10.8] What is the "Named Constructor Idiom"? A technique that provides more intuitive and/or safer construction operations for users of your class. The problem is that constructors always have the same name as the class.

What is initialization in Cpp?

Initialization of a variable provides its initial value at the time of construction. The initial value may be provided in the initializer section of a declarator or a new expression. It also takes place during function calls: function parameters and the function return values are also initialized.

In what order are the data members and bases of a class constructed?

Member variables are constructed in the order in which they are declared in the body of the class. For example: struct A { }; struct B { }; struct S { A a; B b; S() : b(), a() { } }; a is constructed first, then b .

Can I use this pointer in constructor c++?

Some people feel you should not use the this pointer in a constructor because the object is not fully formed yet. However you can use this in the constructor (in the { body } and even in the initialization list) if you are careful.


1 Answers

In all classes construction order is guaranteed: base classes, as specified from left to right followed by member variables in the order declared in the class definition. A class's constructor body is executed once all of its bases' and members' constructions have completed.

In your example X is derived from Z and contains Y so the Z base object is constructed first, then the Y member y, then the construction of the X completes with the execution of X's constructor body.

The temporary W is needed to pass to the constructor of X, so it is constructed before the construction of the x begins and will be destroyed once the initialization of x completes.

So the program must print:

W
Z
Y
X
like image 183
CB Bailey Avatar answered Oct 06 '22 09:10

CB Bailey