为什么析构函数不是默认的虚函数[c++]

Why are destructors not virtual by default [C++]

本文关键字:函数 c++ 析构函数 默认 为什么      更新时间:2023-10-16

为什么c++不将至少有一个虚函数的类默认为虚函数 ?在这种情况下,添加虚析构函数不需要花费任何成本,而不添加虚析构函数(几乎?)总是会出现bug。c++ 0x能解决这个问题吗?

不要为你不需要的东西买单。如果从不通过基指针进行删除操作,则可能不想要间接析构函数调用的开销。

也许您认为虚函数表的存在是惟一的开销。但是也必须考虑到每个单独的函数分派,如果我想让析构函数直接调用分派,我应该被允许这样做。

如果你删除了一个基指针,并且这个类有虚方法,那么你的编译器会警告你的,我想。

编辑:让我把Simon的优秀评论拉到这里:检查这个关于为析构函数生成的代码的SO问题。如您所见,还需要考虑代码膨胀的开销。

下面是一个示例(不是我推荐编写这样的代码):

struct base {
    virtual void foo() const = 0;
    virtual void bar () const = 0;
};
struct derived: base {
    void foo() const {}
    void bar() const {}
};
std::shared_ptr<base>
make_base()
{
    return std::make_shared<derived>();
}

这是没有出现UB的完美代码。这是可能的,因为std::shared_ptr使用类型擦除;最后一次调用delete将删除一个derived*,即使最后一个触发销毁的std::shared_ptrstd::shared_ptr<void>类型。

注意std::shared_ptr的这种行为是不是定制的虚拟销毁;它有多种其他用途(例如std::shared_ptr<FILE> { std::fopen( ... ), std::fclose })。然而,由于该技术已经付出了一些间接工作的代价,一些用户可能对为其基类使用虚析构函数不感兴趣。这就是"只付你需要的"的意思。

按照标准,带有非虚析构函数的多态类不是bug。在这样的对象上执行的一个特定操作会导致未定义的行为,但其他所有操作都是完全正常的。因此,考虑到标准在允许程序员犯什么错误方面的宽容行为,为什么要给予析构函数特殊待遇呢?

而这样的更改会有代价,尽管大多是微不足道的代价:虚表将增加一个元素,并且虚拟分派与析构函数调用相关联。

就我所知,没有,c++ 11中在这方面析构函数的行为没有改变。我想在关于特殊成员函数的那一节中会说些什么,但是它没有,在一般虚函数的那一节中也没有类似的内容。