C++ 默认析构函数可以自动生成为虚拟析构函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1117481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:51:54  来源:igfitidea点击:

Can the default destructor be generated as a virtual destructor automatically?

c++destructor

提问by

Can the default destructor be generated as a virtual destructor automatically?

默认析构函数可以自动生成为虚拟析构函数吗?

If I define a base class but no default destructor, is there a default virtual destructor generated automatically?

如果我定义了基类但没有默认析构函数,是否有自动生成的默认虚拟析构函数?

采纳答案by Uri

No. There is a cost associated with making a method virtual, and C++ has a philosophy of not making you pay for things that you don't explicitly state that you want to use. If a virtual destructor would have been generated automatically, you would have been paying the price automatically.

不。使方法成为虚拟方法是有成本的,而 C++ 的理念是不让您为未明确声明要使用的东西付费。如果虚拟析构函数是自动生成的,那么您将自动付出代价。

Why not just define an empty virtual destructor?

为什么不定义一个空的虚拟析构函数?

回答by Drew Noakes

In C++ 11 you can use:

在 C++ 11 中,您可以使用:

class MyClass
{
  // create a virtual, default destructor
  virtual ~MyClass() = default;
};

回答by Matt

No, all destructor's are by default NOT virtual.

不,默认情况下所有析构函数都不是虚拟的。

You will need to define a virtual destructor on all the base classes

您需要在所有基类上定义一个虚拟析构函数

In addition to that.

在此之上。

To quote Scott Meyers in his book "Effective C++":

引用 Scott Meyers 在他的书“Effective C++”中的话:

The C++ language standard is unusually clear on this topic. When you try to delete a derived class object through a base class pointer and the base class has a non-virtual destructor (as EnemyTarget does), the results are undefined

C++ 语言标准在这个主题上异常清晰。当您尝试通过基类指针删除派生类对象并且基类具有非虚拟析构函数时(如 EnemyTarget 所做的那样),结果未定义

In practice, it's usually a good idea to define a class with a virtual destructor if you think that someone might eventually create a derived class from it. I tend to just make all classes have virtual destructor's anyway. Yes, there is a cost associated with that, but the cost of not making it virtual more often that not out weighs a measly bit of run-time overhead.

在实践中,如果您认为有人最终可能会从中创建一个派生类,那么定义一个带有虚拟析构函数的类通常是一个好主意。无论如何,我倾向于让所有类都具有虚拟析构函数。是的,与此相关的成本是有的,但不经常将其虚拟化的成本会增加微不足道的运行时开销。

I suggest, only make it non-virtual when you're absolutely certain that you want it that way rather than the rely on the default non-virtual that the compilers enforce. You may disagree, however (in summary) I recently had a horrid memory leak on some legacy code where all I did was add a std::vector into one of the classes that had existed for several years. It turns out that one of it's base classes didn't have a destructor defined (default destructor is empty, non-virtual!) and as no memory was being allocated like this before no memory leaked until that point. Many days of investigation and time wasted later...

我建议,仅当您绝对确定要那样做时才将其设为非虚拟,而不是依赖编译器强制执行的默认非虚拟。您可能不同意,但是(总而言之)我最近在一些遗留代码上遇到了可怕的内存泄漏,我所做的只是将 std::vector 添加到已经存在多年的类之一中。事实证明,它的一个基类没有定义析构函数(默认析构函数是空的,非虚拟的!)并且因为在没有内存泄漏之前没有像这样分配内存。很多天的调查和时间浪费了后来......

回答by MSalters

Yes, by inheriting from a base class with a virtual destructor. In this case, you already pay the price for a polymorphic class (e.g. vtable).

是的,通过从具有虚拟析构函数的基类继承。在这种情况下,您已经为多态类(例如 vtable)付出了代价。

回答by Crashworks

Uri and Michael are right -- I'll just add that if what's bugging you is having to touch two files to declare and define the destructor, it's perfectly all right to define a minimal one inline in the header:

Uri 和 Michael 是对的——我只想补充一点,如果你不得不接触两个文件来声明和定义析构函数,那么在标题中定义一个最小的内联文件是完全正确的:

class MyClass
{
   // define basic destructor right here
   virtual ~MyClass(){}

   // but these functions can be defined in a different file
   void FuncA();
   int FuncB(int etc);
}

回答by Thinkeye

Currently, Uriis right. On the other hand, after you have declared a virtual method in your class, you are paying the price for the existence of the virtual table anyway. In fact, the compiler will warn you if your class has a virtual method, but no virtual destructor. This could become a candidate for automatic generation of the default virtual destructor instead of the pesky warning.

目前,Uri是对的。另一方面,在你的类中声明了一个虚方法之后,无论如何你都要为虚表的存在付出代价。事实上,如果你的类有一个虚方法,但没有虚析构函数,编译器会警告你。这可能成为自动生成默认虚拟析构函数而不是讨厌的警告的候选者。

回答by Michael Aaron Safyan

No. You need to declare it as virtual.

不,您需要将其声明为虚拟的。