Java和C#支持的,不能用作与基类类的概念 final
和sealed
关键字.但是,在C++中,如果每个类都有一个虚拟的析构函数,那么就没有什么好的方法可以防止类的派生出于某种困境而导致类被派生出来?
编辑:从C++ 11开始,这不再是真的,你可以指定一个类final
.
一方面给一个对象一个虚拟析构函数意味着它将拥有一个vtable
并因此消耗4个(或64位机器上的8个)每个对象的附加字节vptr
.
另一方面,如果有人后来从这个类派生并通过指向基类的指针删除派生类,程序将是错误定义的(由于没有虚拟析构函数),并且坦率地优化每个对象的指针是荒谬.
在具有虚拟析构函数的抓握手上(可以说是)宣称这种类型意味着多态地使用.
有些人认为,你需要一个明确的理由不使用虚拟析构函数(如的潜台词这个问题)和其他人说,只有当你有理由相信,你的类是从派生你应该使用它们,有什么事你认为?
每个抽象类应该有一个,
受保护的析构函数,或者,
虚拟析构函数.
如果你有一个公共非虚拟析构函数,那就不好了,因为它允许用户通过该指针删除派生对象.因为我们都知道,这是未定义的行为.
对于不打算通过指向它的指针删除的类,没有任何理由拥有虚拟析构函数.它不仅会浪费资源,更重要的是它会给用户一个错误的提示.试想一下,给std::iterator
虚拟析构函数带来多么糟糕的感觉.
问题是,您是否想要强制执行有关如何使用类的规则?为什么?如果一个类没有虚拟析构函数,那么使用该类的任何人都知道它不是从中派生出来的,并且无论如何你都尝试它会有什么限制.那还不够好吗?
或者,如果有人敢做你没预料到的事情,你是否需要编译器抛出一个硬错误?
如果您打算让人们从中派生,那么为该类提供一个虚拟析构函数.否则不要,并假设使用您的代码的任何人都足够聪明,可以正确使用您的代码.
没有!仅当通过基类指针删除派生类的对象时才使用虚拟析构函数.如果您的类不打算在此场景中作为基础,请不要将析构函数设置为虚拟 - 您将发送错误的消息.