Effective_C++:14、总是让base classs拥有virtual destructor

14、总是让base classs拥有virtual destructor

1、为啥让base classs拥有virtual destructor

        在含有继承关系的情况中,让基类的析构函数为虚函数,则在销毁指向派生类的基类指针时,会成功调用派生类的析构函数,否则只调用基类的析构函数。
        有时,需要class跟踪记录他的对象数量,则可以定义一个static成员初始为0,调用构造函数一次令其加1,调用析构函数令其减1,以此记录对象的数量。故,定义一个类EnermyTarget来表示敌军目标,而另一个类EnermyTank来表示敌军坦克,继承于EnermyTarget,他们均含有一个static成员来记录该类对象的数量。
class EnermyTarget {
public:
    EnermyTarget() { ++numTargets; }
    EnermyTarget(const EnermyTarget&) { ++numTargets; }
    ~EnermyTarget() { --numTargets; }
    static size_t numberOfTargets() { return numTargets; }
    virtual bool destroy();
private:
    static size_t numTargets;
};
size_t EnermyTarget::numTargets;
class EnermyTank {
public:
    EnermyTank() { ++numTanks; }
    EnermyTank(const EnermyTank& rhs) : EnermyTarget(rhs) { ++numTanks; }
    ~EnermyTank() { --numTanks; }
    static size_t numberOfTanks() { return numTanks; }
    virtual bool destroy();
private:
    static size_t numTanks;
};
EnermyTarget *targetPtr = new EnermyTank;
...
delete targetPtr;

        以上,targetPtr指针为基类指针,指向了派生类的对象,最后,delete该指针来销毁这个对象。然而此时基类的析构函数不是虚函数,这将引起结果未定义,即产生不可预期的行为,而最有可能的是程序未调用派生类的析构函数,则导致numTanks记录敌军坦克的数量有误。

        因此,需要让基类的析构函数为虚函数,即可成功调用派生类和基类的析构函数。

        有时,我们可能希望构造一个抽象类,不希望被实体化,但是没有什么合适的函数可以声明为纯虚函数,那么你可以声明一个为纯虚函数的析构函数。

2、没有继承关系的类的析构函数

        在含有继承关系的情况下,让基类的析构函数为虚函数。若没有继承关系,则没有必要定义为虚函数,也不应该定义为虚函数。

        首先,我们得知道,为实现虚函数,通常是让对象夹带一些额外信息,即含有一个虚函数表指针,用来在执行期间协助决定使用哪个虚函数。而每个含有虚函数的类都有一个虚函数表,当对象调用虚函数时,编译器根据对象的虚函数表指针所指的虚函数表,决定调用哪个虚函数。即编译器在虚函数表中寻找合适的函数指针。

        我们定义一个只含有两个short int的数据成员,且没有虚函数的类。若short int占16bits,则该类对象可以塞进一个32-bit的缓存器中。甚至,可以把他当作32bit的数据传递给其他语言撰写的函数中。若将该类的析构函数定义为虚函数,则该类含有一个虚函数表,该类对象都含有一个虚函数表指针,则不能将其作为32bit的数据,也不能将其放进32-bit的缓存器中。

3、让base classs拥有virtual destructor

        总之,当一个类作为基类时,其大概率含有虚函数(实现多态),让其析构函数为虚函数。若没有继承关系,不包含虚函数,则不需要声明析构函数为虚函数。

        另外,若将一个是虚函数的析构函数声明为inline,以避免其调用函数的开销。你必须明白,他是虚函数则要求将他的函数指针放进虚函数表中,而inline函数不是一个独立的函数,要取得他的地址,则需要产生一个out-of-line函数副本。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章