Не могли бы вы объяснить, почему следующий код не сбой и как он обрабатывается.Вызов деструктора указателем объекта
class Base
{
public:
Base() {cout << "Base constr" << endl;}
virtual void func() {cout << "Base func()" << endl;}
virtual ~Base() {cout << "Base destr" << endl;}
};
class Layer1 : public Base
{
public:
Layer1() {cout << "Layer1 constr" << endl;}
virtual void func() {cout << "Layer1 func()" << endl;}
virtual ~Layer1() {cout << "Layer1 destr" << endl;}
};
class Layer2 : public Layer1
{
public:
Layer2() {cout << "Layer2 constr" << endl;}
virtual void func() {cout << "Layer2 func()" << endl;}
~Layer2() {cout << "Layer2 destr" << endl;}
};
int main(int argc, char** argv)
{
Layer2 * l2ptr = (Layer2 *) new Base;
l2ptr->func();
delete l2ptr;
return 0;
}
Выход:
Base constr
Base func()
Base destr
Я имею в виду в точке, где удалить называется l2ptr. С первого взгляда кажется, что нужно вызвать деструктор Layer2
, но не был создан объект Layer2
. Кроме того, Layer2
деструктор не virtual
. Когда я делаю это виртуальным, вывод будет таким же. Зачем?
И следующий вопрос: какие проблемы и соображения существуют на объекте родительского класса по его указателю на дочерний класс?
EDIT: Если изменить Layer2
класс к этому
class Layer2 : public Layer1
{
public:
Layer2() {cout << "Layer2 constr" << endl;}
virtual void func() {cout << "Layer2 func()" << endl;}
void func2() {cout << "Layer2 func2()" << endl;}
virtual ~Layer2() {cout << "Layer2 destr" << endl;}
};
И main()
как это:
int main(int argc, char** argv)
{
Layer2 * l2ptr = (Layer2 *) new Base;
l2ptr->func();
l2ptr->func2();
delete l2ptr;
return 0;
}
Он по-прежнему работает, и выход:
Base constr
Base func()
Layer2 func2()
Base destr
Еще раз, Зачем?
Ваш код имеет неопределенное поведение. Это означает, что все может случиться, и вы находитесь на деле, наблюдая, что что-то происходит. –
У вас UB мало после '(Layer2 *) новой базы ... – Jarod42
http://blog.llvm.org/2016/04/undefined-behavior-is-magic.html – JVApen