C++问题:析构函数的多态

来源:百度知道 编辑:UC知道 时间:2024/09/21 11:04:13
普通的多态是在调用的时候根据实际类型确定该调用子类还是父类的同名函数.
子类和父类的析构函数名字肯定是不同的.
通过加virtual修饰,C++是如何实现析构函数的多态的?
例如:
class A
{
....
~A(){cout<<"析构A";}
}
class B:public A
{
....
~B(){cout<<"析构B";}
}
A *b;
b = new B();
delete b;

如果说也是通过实际类型在执行的时候调用自己的析构函数,我觉得有点不太明白,因为析构函数的名字不同,似乎用不着区分该调用子类还是父类的析构函数.
例子中的delete语句肯定不会执行B的析构,只有加virtual修饰之后才执行.

to:godiq,你说的是实际情况如何,这我也知道.但怎么知道派生类是哪个类??

析构函数的工作方式是:最底层的派生类(most derived class)的析构函数最先被调用,然后调用每一个基类的析构函数。

因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分很可能已被销毁,这就导致了一个古怪的“部分析构”对象,这是一个泄漏资源。排除这个问题非常简单:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象,包括全部的派生类部分。

但是,一般如果不做基类的类的析构函数一般不声明为虚函数,因为虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为 vptr(virtual table pointer,虚函数表指针)的指针的形式。vptr 指向一个被称为 vtbl(virtual table,虚函数表)的函数指针数组,每一个包含虚函数的类都关联到 vtbl。当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针。这样子会使类所占用的内存增加。

当一个基类的析构函数声明为虚析构函数,其派生类的析构函数也自动被系统默认为虚函数,当Delete一个指向派生类对像的基数指针时,系统会先调用该派生类对象的析构函数,而后再调用指针本身的基类析构函数.也就是两个类的析构函数都会被调用.

楼主的那段示例代码,则系统只会调用类A的析构函数.因为基类没有声明为虚析构函数.

你是建立的A的指针,当然会先调用A的,当加上virtual 之后编译器就先调用B的,才会在调用A的。