boost :: shared_ptrの代わりにstd :: auto_ptrを使用するのはいつですか?
-
22-07-2019 - |
質問
すべてのコードで boost :: shared_ptr
の使用に移行しましたが、 std :: auto_ptr
を使用するいくつかの孤立したケースがまだあります、シングルトンクラスを含む:
template < typename TYPE >
class SharedSingleton
{
public:
static TYPE& Instance()
{
if (_ptrInstance.get() == NULL)
_ptrInstance.reset(new TYPE);
return *_ptrInstance;
}
protected:
SharedSingleton() {};
private:
static std::auto_ptr < TYPE > _ptrInstance;
};
これが shared_ptr
になっていない非常に良い理由があると言われましたが、私の人生では、なぜだか理解できませんか? auto_ptr
が最終的に次の規格で減価償却としてマークされることを知っているので、この実装を置き換えることができるもの/どのように置き換えることができるかを知りたいです。
また、 shared_ptr
の代わりに auto_ptr
を使用することを検討する他の理由はありますか?そして、何か問題がありますか?将来shared_ptrに移行しますか?
編集:
- したがって、「上記のコードで
auto_ptr
をshared_ptr
に安全に置き換えることができます」の答えは「はい」ですが、パフォーマンスが若干低下します。 。 -
auto_ptr
が最終的に減価償却としてマークされ、std :: shared_ptr
に移行した場合、コードを徹底的にテストして、順守していることを確認する必要があります異なる所有権セマンティクスによって。
解決
auto_ptr
と shared_ptr
は、まったく異なる問題を解決します。一方は他方を置き換えません。
auto_ptr
は、 RAII のセマンティクスを実装するためのポインターの薄いラッパーです。 、例外が発生した場合でもリソースが常に解放されるようにします。 auto_ptr
は、参照カウントなどをまったく行いません。コピーを作成するときに、複数のポインターが同じオブジェクトを指すようにしません。実際、それは非常に異なっています。 auto_ptr
は、代入演算子が source オブジェクトを変更する数少ないクラスの1つです。 auto_ptr Wikipediaページのこの恥知らずなプラグインを検討してください:
int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;
y = x;
cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i
実行方法に注意してください
y = x;
yだけでなくxも変更します。
boost :: shared_ptr
テンプレートを使用すると、同じオブジェクトへの複数のポインターを簡単に処理できます。オブジェクトは、最後の参照がスコープ外になった後にのみ削除されます。この機能は、 Singleton を実装(試行)するシナリオでは役立ちません。シナリオでは、クラスの唯一のオブジェクトへの1つの参照に対する0参照が常に存在します(存在する場合)。
本質的に、 auto_ptr
オブジェクトと shared_ptr
オブジェクトのセマンティクスはまったく異なります(そのため、コンテナーで前者を使用することはできませんが、後者を使用しても問題ありません)。そして、コードの移植中に導入されたリグレッションをキャッチするための優れたテストがあることを確信しています。 :-}
他のヒント
このコードが shared_ptr
の代わりに auto_ptr
を使用する理由を他の人が答えています。他の質問に対処するには:
この実装を何/どのように置き換えることができますか
boost :: scoped_ptr
または unique_ptr
(Boostと新しいC ++標準の両方で利用可能)を使用します。 scoped_ptr
と unique_ptr
の両方が厳密な所有権を提供し(参照カウントのオーバーヘッドはありません)、 auto_ptr
の驚くべきコピーオン削除セマンティクスを回避します。
また、 shared_ptr
の代わりに auto_ptr
の使用を検討する他の理由はありますか?また、将来 shared_ptr
に移行する際に問題が発生しますか?
個人的には、 auto_ptr
は使用しません。コピーオン削除は直感的ではありません。 Herb Sutterは同意しているようです。 scoped_ptr
、 unique_ptr
、または shared_ptr
に切り替えても問題はありません。具体的には、参照カウントのオーバーヘッドを気にしない場合は、 shared_ptr
をドロップインで置き換える必要があります。 scope_ptr
は、 auto_ptr
の所有権の譲渡機能を使用していない場合のドロップイン置換です。所有権の譲渡を使用している場合、 unique_ptr
はドロップインの代わりになりますが、所有権を譲渡するには move
を明示的に呼び出す必要があります。例については、こちらをご覧ください。
auto_ptrは、私が使用する唯一のスマートポインターです。 Boostを使用せず、一般的にビジネス/アプリケーション指向のクラスを明示的に使用することを好むため、これを使用します。 に依存するのではなく、削除のセマンティクスと順序を定義する スマートポインタのコレクション、または個々のスマートポインタ。