web-dev-qa-db-ja.com

このC ++デストラクタは冗長ですか?

次のように定義されたさまざまな構造を持つC++コードを受け取りました。

typedef struct _someStruct_ {
   std::string someString; 
   std::vector<std::string> someVectorOfStrings;
   int  someOtherStuff;

   ~_someStruct_()
   {
      someString.clear();
      someVectorOfStrings.clear(); 
   }
} someStruct; 

ここでのデストラクタは完全に冗長ですか?構造がデフォルトのデストラクタによって破壊された場合、文字列やベクトルなどはとにかく破壊されませんか?

コードを書いていたら、ここに明示的なデストラクタを追加することは考えていなかったでしょう。コンパイラにそれを任せただけです。

私が理解しているように、構造体に独自のデストラクタを作成する必要があるのは、構造体のメンバーのいずれかにクリーンアップが必要なデータへのポインタが含まれている場合、または追加の機能(デバッグ、ロギングなど構造体が削除されます)が必要です。

ここで何かが足りませんか?文字列とベクトルがデストラクタで明示的にクリアされている理由はありますか?私の疑いは、これを送ってくれたのは、実際にはCコードをC++に変換しようとしたCプログラマー(typedefを参照)であるということです。

42
Simon

はい、デストラクタは完全に冗長です。

あなたが自分で言ったように、コードには他の警告サインがあります。たとえば、typedef structを使用しても、C++ではまったく意味がありません。空のデストラクタと同じくらい冗長です。コードは、C++をわずかに把握している誰かによって書かれたものであり、さらに多くの落とし穴があります(1つには、クラスグローバルスコープの先頭にアンダースコアがあるため、名前は無効です)。

70
Konrad Rudolph

実際、これは単に暗黙のデストラクタを使用するよりも悪いです。

明示的なデストラクタを使用することにより、コンパイラは暗黙的な移動コンストラクタを提供しません。

50
Bill Lynch

デストラクタはほぼ完全に冗長です。

それは3つのことをします。

まず、コピー/移動コンストラクターの自動作成と割り当てをブロックします。これは...良いことではないかもしれません。しかし、多分それは望ましいです。しかし、それはそこにいないことと同じではありません。

次に、コンテンツがクリーンアップされる順序を変更します。文字列によって保持されているバッファがクリアされ、次に、ベクトル内の文字列によって保持されている各バッファが破棄され、それらを保持している文字列が破棄されます。次に、未使用のバッファを持つベクトルが破棄されます。メモリが破棄され(メモリが返され)、空になった文字列が破棄されます。

デフォルトのデストラクタでは、順序は、ベクトルの文字列のバッファが破棄され、ベクトルが破棄されている間にベクトルの文字列のメモリが返されます。then文字列は、バッファが返されるとともに破棄されます。

演算子newdeleteに適切なオーバーロードを使用するか、カスタムアロケーターを使用した場合は、これを検出できます。

最後に、このようなデストラクタは、ステップスルーできるため、デバッグが容易な場合があります。

ただし、そのコードを作成した開発者が意図した場合、これらの微妙な影響はない可能性があります。