看看这个:
#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();
}
我给你以下输出:
Derived nonvirtualmethod
Base nonvirtualmethod
Derived virtualmethod
Derived virtualmethod //< invoked by a Base*
pb这是因为指针的静态类型 ( Base*) 和它指向的动态类型( )之间存在差异Derived。虚拟方法和普通方法的区别在于,非虚拟方法遵循静态类型映射(因此Base指针调用Base::方法),而虚拟方法遵循运行时类型链,因此如果 aBase*指向 a Derived,则该Derived方法将被调用.
从这个意义上说,析构函数没有什么特别的:如果它不是虚拟的,Base指针将不会调用Derived它,因此你会得到一个半毁坏的对象,它会被返回给内存存储。
这是 UB(而不是简单地否认)的原因是因为“内存存储”不是由语言本身管理的,而是从程序所在的平台管理的:崩溃很可能取决于缺少该Derived部分(仍然存在)将导致操作系统尝试释放具有错误起始地址的内存块。