-2

スクリーンショット #1: Sample(Sample&) {...) // "const" を使用せずにエラーなし ここに画像の説明を入力 スクリーンショット #2: copy-constructor が含まれていない場合、デストラクタが 2 回呼び出されます。 ここに画像の説明を入力

このコードを VC++2010 で実行すると、驚くべき結果が得られました。

#include <iostream>
using namespace std;

class Sample {
public:
   Sample() { cout<<"Sample().\n"; }
   // Sample (Sample&) { cout<<"Sample(Sample&).\n"; }
   ~Sample() { cout<<"~Sample().\n"; }
};

void fx() {
   throw Sample();
}

int _tmain(int argc, _TCHAR* argv[])
{
   try { fx(); }
   catch (Sample&) { cout<<"Caught Sample.\n"; }
   return 0;
}

例にコピーコンストラクタを含めずに、デストラクタが2回呼び出されている理由を教えてください。たとえば、デストラクタでヒープを解放している場合、そうすると Abort() が発生します。

また、オブジェクトのコピーがスローされたオブジェクトから作成されることも知っていますが、そのためにコピーコンストラクターを呼び出さないのはなぜですか。

コードと出力については、添付のスクリーン ショットを参照してください。

4

1 に答える 1

2

これは、しばらく前からある VC++ コンパイラのバグ (機能? :) のようです (ただし、このステートメントを直接サポートするリンクはなく、検索を続ける時間がありません。これは私自身も 1 回か 2 回遭遇しました。) これは VC++ 2012 でも発生します。

使用しない場合でも、常にコピー ctor を定義することは、良いコーディング プラクティスです。これは3 つのルールの一部です。ただし、注意事項があります。

  1. VC++ は、スロー時にコピー ctor を実行しようとするときに、呼び出し元ではなくオブジェクトのコンテキストを使用します。したがって、非公開とマークされていても、引き続きアクセスできます。これはおそらくレガシーなものですが、その事実に固有のものは見つかりません。

  2. VC++ は、スロー時に非 const パラメータを持つコピー ctor を許可します。これは、移動パラダイムの実装前にリソースを移動できるようにするためのレガシーでもあります。私はそれを漠然と避けていることをいくつか見つけただけです。いいえ、VC ++はオブジェクトをスローするために移動パラダイムを使用していないように見えるため、移動コンストラクターを実装しようとすると、これは依然として発生します。

ムーブ コンストラクターの詳細については、こちらを参照してください。

Microsoft は、C++ 標準のどの部分を実装するかを選択するように見えることに注意してください。このため、私は M$ のコンパイラ開発チームに参加したいとは思いません。:/

于 2013-03-11T17:13:40.680 に答える