3

私が取り組んでいるいくつかのコードを見てきましたが、これと同等のものがあります:

AutoPtr<A> x;
...
/// x gets initialized
...
B* y = new B(x.Detach());

ここで、AutoPtr は auto_ptr のバージョンであり、Detach() は所有されているポインターを返し、それ自体をリセットします。また、B() は x の所有権を取得します。

ここで、new が std::bad_alloc をスローすると x がリークすることに気付いたので、コードを次のように変更しました。

AutoPtr<A> x;
...
/// x gets initialized
...
B* y = new B(x.Get());
x.Detach();

しかし、その後、B() がポインターを「所有」し、その構築中に例外が発生した場合、パラメーター自体を削除する必要がある (またはそうすべきか?) ため、x は B によって 1 回、2 回削除されることに気付きました。 ()、および x のデストラクタによって 1 回。

さて、この問題を回避する C++ イディオムはありますか? たとえば、コンストラクターを呼び出してパラメーターのクリーンアップを担当するコードを作成しますか? 私が見たほとんどのコードはそうではないようです...

4

3 に答える 3

3

...パラメータ自体の削除を処理する必要があります(または削除する必要がありますか?)

いいえ、すべきではありません。

Bコンストラクターが完了するまで存在しません。存在しない場合は、何かの所有権を主張するべきではありません(ある程度、コンストラクター自体が何かをした場合は、それも安全である必要があります)。

C ++のイディオムは、所有権(を含むy)に生のポインターを使用しないことです。呼び出し元がこの方法で所有権を放棄できるように、引数としてBを受け入れる必要があります。これがとAutoPtrの目標です:std::unique_ptrstd::move

std::unique_ptr<A> x;

std::unique_ptr<B> y(new B(std::move(x)));

また、実際newにはこのように使用すべきではないことにも注意してください。代わりに、make_*ユーティリティを使用してください。

auto y = std::make_unique<B>(std::move(x));

しかし、これは現在見落としとして欠けています。

于 2012-10-10T00:28:50.283 に答える
3

AutoPtr<A>明らかな解決策は、次のコンストラクターに一時的なものを渡すことBです。

AutoPtr<B> y(new B(AutoPtr<A>(x));

B*(これにより、返された fromのリソース制御も追加されますnew B())。

Bx.Detach()のコンストラクターは、で初期化する必要があるものを初期化するために呼び出すだけA*です。いずれかの時点で例外が発生すると、AutoPtr<A>はオブジェクトを解放します。

A例外が発生した場合にが管理するオブジェクトを保持したい場合は、代わりに のコンストラクターにxa を渡すことができます。AutoPtr<A>&B

于 2012-10-10T00:26:06.333 に答える
0

このようなものは、次のようになります。

B* y = new B();
y->Attach(x.Detach());

また

B* y = new B();
(*y) = x;
于 2012-10-10T00:29:28.833 に答える