60

デフォルトのデストラクタを自動的に仮想デストラクタとして生成できますか?

基本クラスを定義してデフォルトのデストラクタを定義しない場合、デフォルトの仮想デストラクタが自動的に生成されますか?

4

8 に答える 8

57

いいえ。メソッドを仮想化することにはコストがかかります。C++ には、使用したいことを明示的に述べていないものにお金を払わせないという哲学があります。仮想デストラクタが自動的に生成された場合、料金は自動的に支払われます。

空の仮想デストラクタを定義しないのはなぜですか?

于 2009-07-13T02:06:38.497 に答える
54

C++ 11 では、以下を使用できます。

class MyClass
{
  // create a virtual, default destructor
  virtual ~MyClass() = default;
};
于 2014-02-01T14:44:19.890 に答える
9

いいえ、すべてのデストラクタはデフォルトでは仮想ではありません。

すべての基本クラスで仮想デストラクタを定義する必要があります

それに加えて。

Scott Meyers の著書「Effective C++」を引用すると、次のようになります。

C++ 言語標準は、このトピックに関して非常に明確です。基底クラス ポインターを介して派生クラス オブジェクトを削除しようとしたときに、基底クラスに非仮想デストラクタがある場合 (EnemyTarget のように)、結果は未定義です。

実際には、誰かが最終的に派生クラスを作成する可能性があると思われる場合は、仮想デストラクタを使用してクラスを定義することをお勧めします。とにかく、すべてのクラスに仮想デストラクタを持たせる傾向があります。はい、それに関連するコストはありますが、仮想化を頻繁に行わないことのコストは、わずかな実行時間のオーバーヘッドを上回りません。

コンパイラが強制するデフォルトの非仮想に依存するのではなく、そのようにしたいことが絶対に確実な場合にのみ、非仮想にすることをお勧めします。同意しないかもしれませんが、(要約すると) 最近、いくつかのレガシー コードで恐ろしいメモリ リークが発生しました。数年前から存在していたクラスの 1 つに std::vector を追加しただけです。その基本クラスの 1 つにデストラクタが定義されていないことが判明し (デフォルトのデストラクタは空で、非仮想です!)、その時点までメモリがリークする前に、このようにメモリが割り当てられていなかったためです。何日もの調査と無駄な時間が後で...

于 2009-07-13T03:42:35.687 に答える
8

Uri と Michael は正しいです。デストラクタを宣言および定義するために 2 つのファイルに触れなければならないことが問題である場合は、ヘッダーで最小限の 1 つのインラインを定義してもまったく問題ありません。

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);
}
于 2009-07-13T02:10:40.443 に答える
2

現在、ウリは正しいです。一方、クラスで仮想メソッドを宣言した後は、とにかく仮想テーブルの存在に対して代償を払っています。実際、クラスに仮想メソッドがあり、仮想デストラクタがない場合、コンパイラは警告します。これは、厄介な警告の代わりに、デフォルトの仮想デストラクタの自動生成の候補になる可能性があります。

于 2014-04-07T13:28:30.263 に答える
1

いいえ、仮想として宣言する必要があります。

于 2009-07-13T02:04:38.097 に答える