C ++ 0x移動セマンティクスを使用してオブジェクトが移動された後の、オブジェクトの状態について混乱しています。私の理解では、オブジェクトが移動されても、それはまだ有効なオブジェクトですが、その内部状態が変更されているため、デストラクタが呼び出されたときにリソースの割り当てが解除されません。
しかし、私の理解が正しければ、移動したオブジェクトのデストラクタを呼び出す必要があります。
しかし、私が簡単なテストを実行するとき、それは起こりません:
struct Foo
{
Foo()
{
s = new char[100];
cout << "Constructor called!" << endl;
}
Foo(Foo&& f)
{
s = f.s;
f.s = 0;
}
~Foo()
{
cout << "Destructor called!" << endl;
delete[] s; // okay if s is NULL
}
void dosomething() { cout << "Doing something..." << endl; }
char* s;
};
void work(Foo&& f2)
{
f2.dosomething();
}
int main()
{
Foo f1;
work(std::move(f1));
}
この出力:
Constructor called!
Doing something...
Destructor called!
デストラクタが呼び出されるのは1回だけであることに注意してください。これは、ここでの私の理解がずれていることを示しています。デストラクタが2回呼び出されなかったのはなぜですか?何が起こったのかについての私の解釈は次のとおりです。
Foo f1
構築されます。Foo f1
に渡されwork
、右辺値を取りますf2
。- のmoveコンストラクター
Foo
が呼び出され、すべてのリソースがに移動f1
しf2
ます。 f2
これで、のデストラクタが呼び出され、すべてのリソースが解放されます。- これで、のデストラクタが呼び出されます
f1
が、すべてのリソースがに転送されたため、実際には何も実行されませんf2
。それでも、デストラクタは呼び出されます。
ただし、呼び出されるデストラクタは1つだけなので、ステップ4またはステップ5は実行されません。デストラクタからバックトレースを実行して、どこから呼び出されているかを確認しました。これは、手順5から呼び出されています。では、なぜf2
デストラクタも呼び出されないのでしょうか。
編集:さて、私はこれを変更して、実際にリソースを管理しているようにしました。(内部メモリバッファ。)それでも、デストラクタが1回だけ呼び出される場合と同じ動作が発生します。