使用非虚拟析构函数有什么特别的原因吗? [英] Are there any specific reasons to use non-virtual destructors?

查看:235
本文介绍了使用非虚拟析构函数有什么特别的原因吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为我知道,任何被指定有子类的类都应该使用虚拟析构函数来声明,所以类实例在通过指针访问它们时可以被正确地销毁。

As I know, any class that is designated to have subclasses should be declared with virtual destructor, so class instances can be destroyed properly when accessing them through pointers.

但是为什么甚至可以用非虚拟析构函数声明这样的类呢?我相信编译器可以决定什么时候使用虚拟析构函数。那么,是C ++设计监督,还是我缺少一些东西?

But why it's even possible to declare such class with non-virtual destructor? I believe compiler can decide when to use virtual destructors. So, is it a C++ design oversight, or am I missing something?

推荐答案


使用非虚拟析构函数的具体原因?

Are there any specific reasons to use non-virtual destructors?

是,有。

主要是归结为性能。虚函数不能被内联,而是必须首先确定要调用的正确函数(这需要运行时信息),然后调用该函数。

Mainly, it boils down to performance. A virtual function cannot be inlined, instead you must first determined the correct function to invoke (which requires runtime information) and then invoke that function.

在性能敏感的代码中,无代码和简单函数调用之间的区别可以有所不同。与许多语言不同,C ++并不认为这种差异是微不足道的。

In performance sensitive code, the difference between no code and a "simple" function call can make a difference. Unlike many languages C++ does not assume that this difference is trivial.


但是为什么甚至可以用非虚拟析构函数

But why it's even possible to declare such class with non-virtual destructor?

因为很难知道(对于编译器)类是否需要一个虚拟析构函数。

Because it is hard to know (for the compiler) if the class requires a virtual destructor or not.

在以下情况下需要虚拟析构函数:

A virtual destructor is required when:


  • 您调用 delete

当指定一个指针时,指向
<编译器看到类定义:

When the compiler sees the class definition:


  • 它不知道你打算从这个类派生 - 虚拟方法

  • 但更令人生畏:它不能知道你打算调用 delete b

许多人假设多态性需要新建实例,这只是缺乏想象力:

Many people assume that polymorphism requires newing the instance, which is just sheer lack of imagination:

class Base { public: virtual void foo() const = 0; protected: ~Base() {} };

class Derived: public Base {
  public: virtual void foo() const { std::cout << "Hello, World!\n"; }
};

void print(Base const& b) { b.foo(); }

int main() {
  Derived d;
  print(d);
}

在这种情况下,不需要支付虚拟析构函数在销毁时间没有涉及多态性。

In this case, there is no need to pay for a virtual destructor because there is no polymorphism involved at the destruction time.

最后,这是一个哲学问题。在实践中,C ++默认选择性能和最小服务(主要例外是RTTI)。

In the end, it is a matter of philosophy. Where practical, C++ opts for performance and minimal service by default (the main exception being RTTI).

。有两个警告可以用来发现问题:

With regards to warning. There are two warnings that can be leveraged to spot the issue:


  • -Wnon-virtual-dtor除非基类中的析构函数 protected (gcc,Clang):每当有虚函数的类不声明虚拟析构函数时, 。这是一个悲观的警告,但至少你不会错过任何东西。

  • -Wnon-virtual-dtor (gcc, Clang): warns whenever a class with virtual function does not declare a virtual destructor, unless the destructor in the base class is made protected. It is a pessimistic warning, but at least you do not miss anything.

-Wdelete-non-virtual-dtor (Clang, ported to gcc too ):警告每当 delete 被指向一个有虚函数但没有虚析构函数,除非类被标记为 final 。它有一个0%的假阳性率,但警告晚(可能多次)。

-Wdelete-non-virtual-dtor (Clang, ported to gcc too): warns whenever delete is invoked on a pointer to a class that has virtual functions but no virtual destructor, unless the class is marked final. It has a 0% false positive rate, but warns "late" (and possibly several times).

这篇关于使用非虚拟析构函数有什么特别的原因吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆