У меня есть иерархия классов, где в производном классе объявлен объект класса Dog. Затем этот объект предоставляется в базовый класс в списке инициализации.Почему неконструированный объект может быть передан конструктору базового класса в производный список инициализации
Поскольку объект класса Dog не сконструирован до того, как вызывается конструктор базового класса, так что объект не должен использоваться. Но я вижу, что этот объект может быть использован в следующем коде:
#include <iostream>
using namespace std;
class Dog {
public:
Dog() {cout << "\n In Dog";}
void dfoo(){cout << "\n In dfoo";};
};
class Foo {
public:
Foo(Dog d){cout << "\n In Foo";
d.dfoo();
}
};
class Bar : public Foo {
Dog d;
public:
Bar() : Foo(d) {
cout << "\n In Bar";
}
};
int main() {
cout << "\nHello";
Bar b;
}
Выход:
Hello In Foo In dfoo In Dog In Bar
Выходные данные показывают, что dfoo() была вызвана еще до объекта Dog был построен. Как это работает так? Не следует ли «d» быть мусором, поскольку это не инициализируется до вызова конструктора базы?
Как конструктор Foo может принять объект мусора, если он требует правильной собаки? – DKR
Ошибка, когда программист сделал что-то неправильно, никогда не был главной целью проекта C++. Предполагается, что программы на C++ работают достаточно эффективно при правильной кодировке. Это ожидание эффективности устраняет большинство возможностей здравомыслия, проверяя действия программиста. Конструктор Foo не требует «правильной собаки». Это требует только того, что вы утверждаете, является Собакой. Тогда Dog :: dfoo() также требует только то, что вы утверждали как Собака (это фактически не использует этот объект). – JSF
Добавление виртуальной функции в класс Dog и вызов этого объекта d из Foo имеет тот же эффект. Нет ошибки. – DKR