不在构造函数和析构函数中调用virtual函数
1.不在构造函数中调用virtual函数
例如
class Base{
public:
Base();
virtual void func1() const=0;
}
Base::Base()
{
//...
func1();
}
class Derived:public Base
{
public:
virtual void func1() const;
}
当Derived d被执行时,首先调用的是基类Base的构造函数,在Base构造函数内调用func1是不合适的,因为func1在基类中是一个纯虚函数,没有定义,此时的子类Derived对象还没有被建立。也就是执行基类的构造函数时,该对象的派生类部分是为被初始化的状态;
如果在构造函数中想要调用子类中的接口,可以通过将子类的信息传递到父类中的构造函数中去,例如:
class Base
{
public:
Base(String str);
void func1(String str);
}
Base(String str)
{
//....
func1(str);
}
class Derived:public Base
{
public:
Derived (str)
:Base(str)
{//.....}
}
2.在析构函数中调用虚函数也没有意义
销毁派生类对象的次序和构造函数时的次序相比正好是相反的,因为当执行基类的构造函数时,在基类的构造函数中调用派生类的虚函数,这时派生类部分已经被销毁了。即执行基类成员的时候,该对象处于未完成的状态。
综上所述:如果构造函数或析构函数调用了某个虚函数,则我们应该执行与构造函数或析构函数所属类型相对应的虚函数版本。