讨论virtual析构函数

1、什么时候需要virtual析构函数?
polymorphic(带多态性质的)base class应该声明一个virtual析构函数。就是说,如果class带有任何virtual函数,它就应该有一个virtual析构函数。

#include <cstdio>
#include <cstring>

class Base
{
public:
    Base(const char *s)
    {
        if(s)
        {
            int len = strlen(s);
            m_base_name = new char[len+1];
            strcpy(m_base_name, s);
        }
    }
    ~Base()//
    {
        printf("Base destruct\n");
        if(m_base_name)
        {
            delete [] m_base_name;
        }   
    }
private:
    char *m_base_name;
};

class Derived : public Base
{
public:
    Derived(const char *s1, const char *s2):Base(s1)
    {
        if(s2)
        {
            int len = strlen(s2);
            m_derived_name = new char[len+1];
            strcpy(m_derived_name, s2);
        }
    }
    ~Derived()
    {
        printf("Derived destruct\n");
        if(m_derived_name)
        {
            delete [] m_derived_name;
        }   
    }

private:
    char *m_derived_name;
};

int main(int argc, char **argv)
{
    Base *p = new Derived("base name", "derived name");
    delete p;

    return 0;
}

执行结果是:Base destruct
new出来的Derived对象仅基类成分被销毁了。c++明白指出,当derived class对象经由一个base class指针删除,而该base class带着一个non-virtual析构函数,其结果未定义。反之,如果此处将Base类的析构函数声明为虚函数,当执行“delete p;” 时,就能根据p所指对象的虚函数表找到正确的析构函数版本。将析构函数声明为虚函数,与将一般的函数声明为虚函数有一点不同,那就是基类中虚函数名字和派生类的虚函数名字不相同,这是虚函数的一种特殊情形。

2、什么时候不需要virtual析构函数?
classes的设计目的不是为了具备多态性(polymorphically),就不该声明virtual析构函数。

(1) virtual函数会导致对象体积的增大(用于存放virtual table pointer)。
(2) virtual table pointer的存在,导致class的结构与其他语言(如C语言)内的相同声明的结构不一样,因此可移植性变弱了。
例如:

//c++
class Point
{
public:
    Point(int x, int y);
    ~Point();
private:
    int m_x;
    int m_y;
};

//c
struct Point
{
    int x;
    int y;
};

以上声明有相同的内存结构。但是class Point里面如果有虚函数,那么它们的结构就不相同了。

3、延伸:classes的设计目的不是为了具备多态性(polymorphically)时,使用它们时需要注意的问题。

class SpecialString : public std::string
{
    ...
};

SpecialString *pss = new SpecialString("Impending Doom");
std::string *ps;
...
ps = pss;
...
delete ps;  //未定义

相同的分析适用于任何不带virtual析构函数的class,包括所有的STL容器,如vector,list,set等等。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值