Просто посмотрите на это:
#include <iostream>
class Base
{
public:
void nonvirtualmethod()
{ std::cout << "Base nonvirtualmethod" << std::endl; }
virtual void virtualmethod()
{ std::cout << "Base virtualmethod" << std::endl; }
};
class Derived: public Base
{
public:
void nonvirtualmethod()
{ std::cout << "Derived nonvirtualmethod" << std::endl; }
virtual void virtualmethod()
{ std::cout << "Derived virtualmethod" << std::endl; }
};
int main()
{
Derived d;
Derived* pd = &d;
Base* pb = &d; //< NOTE: both pd and pb point to the same object
pd->nonvirtualmethod();
pb->nonvirtualmethod();
pd->virtualmethod();
pb->virtualmethod();
}
I дает следующий результат:
Derived nonvirtualmethod
Base nonvirtualmethod
Derived virtualmethod
Derived virtualmethod //< invoked by a Base*
Это происходит потому, что есть разница между статическим типом pb
указателя (Base*
) и динамический тип, на который он указывает (Derived
). Разница между виртуальными и обычными методами заключается в том, что не виртуальные методы следуют за сопоставлением статического типа (поэтому указатель Base
вызывает методы Base::
), тогда как виртуальные методы следуют цепочке типов времени выполнения, следовательно, если Base*
указывает на Derived
, вызывается метод Derived
.
деструкторы, в этом смысле, ничего особенного: если это не виртуальная, Base
указатель не будет вызывать Derived
один, следовательно, вы остались с полуразрушенного объекта, который возвращается в магазин памяти.
Причина, по которой это UB (а не просто отказ), заключается в том, что «хранилище памяти» не управляется самим языком, а с платформы, на которой размещена программа: авария, скорее всего, зависит от факта что отсутствующая часть Derived
(все еще живая) приведет к тому, что операционная система попробует освободить блок памяти с неправильным стартовым адресом.
Деструктор базового класса должен быть «виртуальным» – Mohammad
, вы должны сделать виртуальный виртуальный демер вашего базового класса, см. Эту ссылку для получения более подробной информации http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq -20.7 – Sanish
он сработал * после * или написал «Base :: Base DTOR» или он никогда не записывал это? – Walter