构造函数不能够是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,若是构造函数是虚的,就须要一个虚函数表来调用,可是类还没实例化没有内存空间就没有虚函数表,这根本就是个死循环。函数
但是析构函数却要定义成虚函数,这是为何呢,写一个很是简单的例子来理解一下:spa
class AA { public: AA() {}; ~AA() { fun2(); }; virtual void fun1() { cout << "Base construct" << endl; } virtual void fun2() { cout << "Base destruct" << endl; } }; class BB : public AA { public: BB() { fun1(); }; ~BB() { fun2(); }; void fun1() { cout << "Derive construct" << endl; } void fun2() { cout << "Derive destruct" << endl; } }; int main() { for (int i = 0; i < 1; i++) { //AA a; BB b; } return 0; }
输出结果:code
因此能够看出,派生类对象构造的时候先调用基类的构造函数再调用派生类的构造函数,析构的时候先调用派生类析构函数再调用基类析构函数。对象
其实这个很好理解,派生类的成员由两部分组成,一部分是从基类那里继承而来,一部分是本身定义的。那么在实例化对象的时候,首先利用基类构造函数去初始化从基类继承而来的成员,再用派生类构造函数初始化本身定义的部分。blog
同时,不止构造函数派生类只负责本身的那部分,析构函数也是,因此派生类的析构函数会只析构本身的那部分,这时候若是基类的析构函数不是虚函数,则不能调用基类的析构函数析构从基类继承来的那部分红员,因此就会出现只删一半的现象,形成内存泄漏。继承
因此析构函数要定义成虚函数。内存