У меня есть некоторые сомнения относительно конструкции и гарантий порядка инициализации в C++. Например, следующий код имеет четыре класса X
, Y
, Z
и W
. Основная функция инстанцирует объекта class X
, который содержит объект class Y
, и происходит из class Z
, таким образом, обоих конструкторов вызовут. Кроме того, const char*
параметр передал X
конструктор будет неявно преобразован в объект class W
, так W
конструктора нужно также вызвать.
То, что гарантии являются стандартом C++, дает на порядке вызовов конструкторам копии? Или, эквивалентно, что этой программе позволяют распечатать?
#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;
}
править: Это корректно?
W |
/ \ |
Z Y |
\ / |
X V
Во всех классах гарантируется порядок построения: базовые классы, указанные слева направо, за которыми следуют переменные-члены в порядке, объявленном в определении класса. Тело конструктора класса выполняется после завершения всех построений его баз и членов.
В вашем примере X
является производным от Z
и содержит Y
, поэтому сначала создается базовый объект Z
, затем Y
член y
, затем построение X
завершается выполнением тела конструктора X
.
Временный W
необходим для передачи конструктору X
, поэтому он создается до начала построения x
и будет уничтожен один раз инициализация x
завершается.
Итак, программа должна напечатать:
W
Z
Y
X
1) Прежде всего, необходимо вычислить аргументы.
2) Затем строятся базовые классы.
3) Затем члены конструируются в порядке их появления в объявлении класса.
4) Тогда Конструктор X называется
Чтобы расширить ответ Чарльза Бейли, правила меняются, когда ваши базовые классы наследуются виртуально. Я всегда забываю, каков порядок, на сайте IBM сказано, что виртуальные базы инициализируются первыми, но я просто никогда не сталкивался со случаем, когда это было бы не просто мелочью.