.#include<iostream>
using namespace std;
class A
{
public:
A(){cout <<"A"<<endl;}
virtual ~A(){cout <<"~A"<<endl;}
};
classB : public A
{
public:
B(){cout <<"B"<<endl;}
virtual ~B(){cout <<"~B"<<endl;}
};
int main()
{
A*p =new B;
deletep;
return 0;
}
-----------
说明虚析构函数的目的在于在使用delete运算符删除一个对象时,能保析构函数被正确地执行
如上例子如果基类的析构函数没有声明为虚析构函数(也就是把virtual去掉)
那么输出的结果是A
B
~A
而派生类B的虚构函数没有被调用,导致内存泄漏
如果声明为虚析构函数则输出的结果是
A
B
~B
~A
---------------=====================
我的理解:有两种情况是要定义虚析构的
1.如果基类中有虚函数,否则如所说,用基类指针去析构派生类,会析构不完全。
2.如果派生类自定义了operatordelete()函数,这时不管基类中是否有没有虚函数都要虚析构。否则会用你不希望的方式去析构。
==================================================================
如果子类覆盖的父类的虚函数
则父类的指针或引用实际指向子类的对象
那通过该指针或引用调用虚函数时,则将调用子类的(虚)函数,如果不是虚函数,则将调用父类的函数
=================================================================
1)虚函数是动态绑定的,也就是说,使用虚函数的指针和引用能够正确找到实际类的对应函数,而不是执行定义类的函数。这是虚函数的基本功能,就不再解释了。
2) 构造函数不能是虚函数。而且,在构造函数中调用虚函数,实际执行的是父类的对应函数,因为自己还没有构造好,多态是被disable的。
3) 析构函数可以是虚函数,而且,在一个复杂类结构中,这往往是必须的。
4) 将一个函数定义为纯虚函数,实际上是将这个类定义为抽象类,不能实例化对象。
5) 纯虚函数通常没有定义体,但也完全可以拥有。
6)析构函数可以是纯虚的,但纯虚析构函数必须有定义体,因为析构函数的调用是在子类中隐含的。
7) 非纯的虚函数必须有定义体,不然是一个错误。
8)派生类的override虚函数定义必须和父类完全一致。除了一个特例,如果父类中返回值是一个指针或引用,子类override时可以返回这个指针(或引用)的派生。例如,在上面的例子中,在Base中定义了virtual Base* clone(); 在Derived中可以定义为 virtual Derived*clone()。可以看到,这种放松对于Clone模式是非常有用的。
其他,有待补充。
zz http://www.cnblogs.com/chio/archive/2008/09/04/888260.html
============================================================================
那么在、当pBase指针被撤消时,调用的是CBase的析构函数还是CChild的呢?
显然是CBase的(静态联编)。但如果把CBase类的析构函数改成virtual型,当pBase指针被撤消时,就会先调用CChild类析构函数,再调用CBase类析构函数(特别是当派生类中已经存在内存的申请,析构函数中存在内存的释放)
================================================================
构造函数为什么不能虚化:
1构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功。编译器无法知道对象的实际类型,是该类本身,还是该类的一个派生类,或是更深层次的派生类。无法确定。。。
2虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表还没有被初始化,将无法进行。
===============================================================
模板成员函数不能为虚函数:
当前的编译器都期望在处理类的定义的时候就能确定这个类的虚函数表的大小,如果允许有类的虚成员模板函数,那么就必须要求编译器提前知道程序中所有对该类的该虚成员模板函数的调用,而这是不可行的。
==============================================================