次のコードは、学習演習として、Windows デスクトップ用の Visual Studio 2012 Express でコンパイルおよび実行されました。
#include <cstdio>
class X
{
public:
X() { printf("default constructed\n"); }
~X() { printf("destructed\n");}
X(const X&) { printf("copy constructed\n"); }
X(X&&) { printf("move constructed\n"); }
X & operator= (const X &) { printf("copy assignment operator\n"); }
};
X A() {
X x;
return x;
}
int main() {
{
A();
}
std::getchar();
}
コンパイラの最適化を無効にしてコンパイルした場合 (/Od)、結果の出力は、デストラクタが 2 回呼び出されたことを示します。オブジェクトが 1 つしか構築されていない場合、これは問題です。デストラクタが 2 回呼び出されるのはなぜですか? クラスが独自のリソースを管理している場合、これは問題になりませんか?
default constructed
move constructed
destructed
destructed <<< Unexpected call
出力を説明するためにいくつかの実験を試みましたが、最終的にこれらは有用な説明につながりませんでした。
実験 1: 最適化を有効にして (/O1 または /O2) 同じコードをコンパイルすると、結果の出力は次のようになります。
default constructed
destructed
これは、名前付き戻り値の最適化がムーブ コンストラクターの呼び出しを省略し、根本的な問題を隠したことを示しています。
実験 2: 最適化を無効にし、移動コンストラクターをコメントアウトしました。生成された出力は、私が期待したものでした。
default constructed
copy constructed
destructed
destructed