1 c++明确指出,当派生类对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义---实际执行时通常发生得是子类对象得derived成分没有被销毁,消除这个问题得做法很简单,给base类一个虚拟构函数,此后删除派生类对象就会如你想要得那般,是的,他会消除整个对象,包括派生类成分
class TimeKeeper
{
public:
virtual ~TimeKeeper()
{
cout << "~TimeKeeper" << endl;
}
};
class AtomicClock :public TimeKeeper{
public:
~AtomicClock()
{
cout << "~AtomicClock" << endl;
}
};
int main()
{
TimeKeeper *ptk = new AtomicClock;
delete ptk;
}
任何class只要带virtual函数几乎确定应该有一个vritual 析构函数,如果class不含virtual函数,通常表示它并不意味着用作class,当class不企图当作virtual class,令其是个virtual 函数是个馊主意,因为virtual 会有一个vptr指针,对象体积会增加
2 即使class完全不带virtual 函数,被non-virtual析构函数问题给咬伤还是有可能的,比如用string类型或者stl容器作为基类,当把派生类对象转为为基类时,然后将转换所得的基类指针delete掉时,你立即就会被流放到“行为不明确 ”恶地上
#include <iostream>
#include <string>
using namespace std;
class SpecialString :public string
{
public:
SpecialString(string str) :str(str){}
~SpecialString()
{
cout << "~SpecialString" << endl;
}
private:
string str;
};
int main()
{
SpecialString *pass = new SpecialString("hello,world");
string *ps = pass;
delete ps; //未有定义,因为*ps的SpecialString资源会泄漏,因为SpecialString类的析构函数没有被调用
}3 纯虚函数是不能被实例化,也就是说,不能够创建对象,但是有时候你希望拥有抽象类,但手中没有纯虚函数怎么办?由于抽象类企图被用作一个base class,但由于抽象类应该有个虚析构函数,并且由于纯虚函数会导致抽象类,因此解法很简单,为你希望成为抽象的那个class声明一个纯虚析构函数
class Wow
{
public:
virtual ~Wow()=0;
};析构函数的运行方式是,最深层派生的那个class其析构函数现被调用,然后是其每一个base class的析构函数被调用,编译器会在Wow的派生类的i狗函数中创建一个对~Wow的调用动作,所以你必须要为这个函数提供一个定义,连接器会发生抱怨
给base class一个虚析构函数,这个规则只适合用于带多态的base class上,这种基类的设计目的是为了用来通过基类处理派生类对象(父类作为接口,父类指针指向子类对象)
请记住:
多态性质的基类应该声明一个虚析构函数,如果class带有虚函数,他就应该拥有一个虚析构函数
classes的设计目的如果不是作为一个base class,或不是为了具有多态性,就不该声明virtual析构函数