Why are destructors not virtual by default [C++]
为什么C++没有为具有至少一个其他虚函数的类默认析构函数虚化?在这种情况下,添加一个虚拟析构函数不需要花费任何代价,而没有一个是(几乎是?)总是一个bug。C++ 0x会解决这个问题吗?
你不为你不需要的东西付钱。如果从不通过基指针删除,则可能不需要间接析构函数调用的开销。
也许你在想,只有vtable的存在才是唯一的开销。但是每个单独的函数分派也必须考虑,如果我想让析构函数直接调用分派,应该允许这样做。
如果您删除了一个基指针,并且该类有虚拟方法,那么编译器会很好地警告您。
编辑:让我把西蒙的精彩评论放到这里:看看这个关于为析构函数生成的代码的问题。如您所见,还需要考虑代码膨胀的开销。
下面是一个例子(我不建议编写这样的代码):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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。这是可能的,因为
请注意,
根据标准的字母,具有非虚拟析构函数的多态类不是bug。对这样一个对象执行一个特定的操作会导致不确定的行为,但其他的一切都是完全洁净的。因此,考虑到本标准在允许程序员犯什么错误方面的宽松行为,为什么应该对析构函数进行特殊处理?
这样的更改将带来成本,尽管大部分是微不足道的:虚拟表将是一个更大的元素,以及与析构函数调用相关联的虚拟分派。
据我所知,在C++ 11中,析构函数的行为没有变化。我想它会在关于特殊成员函数的小节中说些什么,但它不会,而且一般来说,虚拟函数的小节中也没有类似的内容。