В каком порядке будут вызываться конструкторы при построении объекта класса C в следующей иерархии классов
В каком порядке будут вызываться конструкторы при построении объекта класса C в следующей иерархии классов:
class A{ };
class B: public A{ };
class D: public A{ };
class C: public D, public B{ };
int main{} {C obj;}
Ответы (2 шт):
В приведенном фрагменте - ни в каком, потому что компилятор споткнется на
int main{}
Но если заменить фигурные скобки на круглые, то конструктор С приведет к вызову конструкторов D и B в порядке их упоминания в наследовании, а каждый из них, в свою очередь, к вызову конструктора A (наследование не виртуальное).
Т.е. ADABC.
Вот если наследование виртуальное
class B: virtual public A ...
class D: virtual public A ...
то тогда - ADBC.
Легко проверить, написав соответствующий вывод конструкторами...
Вопрос заковыристый.
Если добавить вывод в тела конструкторов, то выведено будет ADABC (как сказал @Harry), но это неправильный ответ.
Перед тем, как зайти в свое тело, конструктор вызывает конструкторы родителей; они не сами вызываются. Поэтому настоящий порядок: CDABA.
Чтобы было более наглядно, можно поменять код вот так:
#include <iostream>
int foo(const char *text)
{
std::cout << text;
return 42;
}
class A
{
public:
A(int)
{
std::cout << "Тело A()\n";
}
};
class B : public A
{
public:
B(int)
: A(foo("B() вызывает A()\n"))
{
std::cout << "Тело B()\n";
}
};
class D : public A
{
public:
D(int)
: A(foo("D() вызывает A()\n"))
{
std::cout << "Тело D()\n";
}
};
class C : public D, public B
{
public:
C(int)
: D(foo("C() вызывает D()\n")), B(foo("C() вызывает B()\n"))
{
std::cout << "Тело C()\n";
}
};
int main()
{
C obj(42);
}
Вывод будет:
C() вызывает D()
D() вызывает A()
Тело A()
Тело D()
C() вызывает B()
B() вызывает A()
Тело A()
Тело B()
Тело C()
То есть в первую очередь выполняется список инициализации в конструкторе C().