构造函数不能是虚函数
1、创建一个对象必须明确指出它的类型,否则无法创建,一个对象创建成功,编译器获得它的实际类型,然后去调用对应的函数,而如果构造函数声明为虚函数,会形成一个死锁,虚函数是在运行才能确定确定其调用哪一个类型的函数,而具体哪一个类型是编译器通过对象的类型去确定的,但是此时对象还未创建也就没法知道其真实类型。
2、虚函数对应一张虚函数表,这个虚函数表是存储在对象的内存空间的,如果构造函数是虚函数就需要通过虚函数表来调用,可是对象还没有实例化,也就是内存空间还没有,找不到虚函数表,所以构造函数是不能声明为虚函数的。
析构函数可以是虚函数
若不将基类的析构函数声明为virtual,通过基类指针删除派生类对象时,通常情况下只会调用基类的析构函数。但是,删除一个派生类的对象时,应该先调用派生类的析构函数,然后调用基类的析构函数。
因此,一般来说,一个类如果定义了虚函数,则应该将析构函数也定义成虚函数;或者说,一个类打算作为基类使用,也应该将析构函数定义成虚函数。这样在通过基类指针删除派生类对象时,会首先调用派生类的析构函数,然后调用基类的析构函数。
注:若在构造函数和析构函数中调用虚函数,不是多态。因为编译时即可确定,调用的函数是自己的类或基类中定义的函数,不会等到运行时才决定调用自己的还是派生类的函数。