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
[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.
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.
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 .
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With