说明: 1.如果一个类是作为基类使用,那么他的虚构函数一定要是虚的,即用virtual关键字(参数为零则为纯虚函数). 否则会有内存泄漏(很重要),因为当用基类的指针删除一个派生类的对象时,要调用派生类的析构函数.但是 其子类或者子子类可以的析构函数可以是虚函数,也可以不是虚函数.(不加virtual 关键字则不会调用派生 类的析构函数,而上面用了ClxBase *pTest = new ClxDerived;语句也就是new的ClxDerived对象没有 销毁,所以产生内存泄漏) 2.类中的虚函数,如果一个类中的函数被声明成为虚函数,那么其子类不用在声明为虚函数(当子类还有子类时), 也可以声明为虚函数.结果是一样的.同虚析构函数的道理是一样的.当然,并不是要把所有类的析构函数都写 成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就 会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
具体例子:
#include "iostream.h"
class ClxBase { public: ClxBase() {}; virtual ~ClxBase() { cout << "Output from the destructor of class ClxBase!" << endl; }; virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; };
class ClxDerived : public ClxBase { public: ClxDerived() {}; virtual~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };
//此处的virtual可以去掉 virtual void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
//此处的virtual可以去掉 };
class ClxThrived : public ClxDerived { public: ClxThrived(){}; virtual ~ClxThrived(){cout << "Output from the destructor of class ClxThrived!" << endl;};
//此处的virtual可以去掉 virtual void DoSomething(){cout << "Do something in class ClxThrived!" << endl;}
//此处的virtual可以去掉 }; void main() { ClxBase *pTest1 = new ClxBase; pTest1->DoSomething(); delete pTest1;//1
ClxBase *pTest2 = new ClxDerived; pTest2->DoSomething(); delete pTest2;//2 用基类的指针删除一个派生类的对象时
ClxDerived *pTest3 = new ClxDerived; pTest3->DoSomething(); delete pTest3;//3
ClxBase *pTest4 = new ClxThrived; pTest4->DoSomething(); delete pTest4;//4 用基类的指针删除一个派生类的对象时
ClxDerived *pTest5 = new ClxThrived; pTest5->DoSomething(); delete pTest5;//5 用基类的指针删除一个派生类的对象时
ClxThrived *pTest6 = new ClxThrived; pTest6->DoSomething(); delete pTest6;//6 } |