std :: auto_ptrからstd :: unique_ptr


185

新しい標準(および一部のコンパイラですでに利用可能なパーツ)が登場したことで、新しいタイプstd::unique_ptrはの代わりになるはずですstd::auto_ptr

それらの使用法は正確にオーバーラップしていますか(コードでグローバル検索/置換を実行できます(そうするわけではありませんが、そうした場合))、またはドキュメントを読んでも明らかでないいくつかの違いに注意する必要がありますか?

また、直接置換する場合は、単にstd::auto_ptr?を改善するのではなく、新しい名前を付けるのはなぜですか。

回答:


219

auto_ptr(既知の結果とともに)をコピーできるため、グローバルな検索/置換はできませんが、unique_ptr移動のみが可能です。どんなものでも

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

少なくともこのようになる必要があります

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

その他の違いについてunique_ptrは、配列を正しく処理できます(は呼び出されますがdelete[]、は呼び出さauto_ptrれますdelete


101
一方、この検索/置換を実行してもコンパイルエラーが発生するだけで、コードが暗黙的に壊れることはありません。したがって、後でコンパイルエラーを手動で修正すれば安全です
jalf

7
@jalf:確かに、auto_ptrsとunique_ptrsのUBで明確に定義される反例は思いつきません。
Cubbi

1
したがって、unique_ptrはauto_ptrの拡張機能のようです。配列をサポートし、あいまいさを排除してください
Baiyan Huang

92

std::auto_ptrそしてstd::unique_ptrsomewaysなどで代替の低下に互換性がありません。したがって、検索/置換を行うだけでは不十分です。ただし、コンパイルエラーを処理して検索/置換を行うと、奇妙なコーナーケースを除くすべてが修正されます。ほとんどのコンパイルエラーでは、を追加する必要がありstd::moveます。

  • 関数スコープ変数:
    別の関数に値で渡さない限り、100%互換性があります。
  • 戻り値の型:
    100%互換ではありませんが、99%互換は問題ありません。
  • 値による関数パラメーター:
    1つの警告と100%互換性がunique_ptrあります。s はstd::move呼び出しを通じて渡す必要があります。正しくないとコンパイラが文句を言うので、これは簡単です。
  • 参照による関数パラメーター:
    100%互換。
  • クラスメンバー変数:
    これはトリッキーです。 std::auto_ptrコピーのセマンティクスは悪です。クラスがコピーを許可しない場合、それstd::unique_ptrは置き換えのドロップです。ただし、クラスに適切なコピーセマンティクスを提供しようとした場合は、std::auto_ptr処理コードを変更する必要があります。正しくないとコンパイラが文句を言うので、これは簡単です。特別なコードなしでstd::auto_ptrメンバー持つクラスのコピーを許可した場合は、あなたに恥と幸運を祈ります。

要約するstd::unique_ptrと、壊れていないstd::auto_ptrです。を使用するときにエラーになることが多かった動作をコンパイル時に許可しませんstd::auto_ptr。したがって、std::auto_ptr必要に応じて注意して使用する場合、への切り替えstd::unique_ptrは簡単です。std::auto_ptrの奇妙な動作に依存している場合は、とにかくコードをリファクタリングする必要があります。


8
「とにかくコードをリファクタリングする必要がある」ための+1。auto_ptrsは、20.4.5 / 3が優れていると言っている場合にのみ適しています。
Cubbi

8
これに加えて、コードのauto_ptrをunique_ptrに置き換えて、コンパイルエラーを修正してください。これで明らかになるバグの数に驚くでしょう。
Bartosz Milewski、2010年

36

私の知る限り、unique_ptr直接の代替品ではありません。修正される主な欠陥は、所有権の暗黙の移転です。

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

一方、unique_ptrは完全に新しい機能を備えています。コンテナに格納できます。


8
Scott Meyersは、彼の「Effective C ++」(第3版)項目13(64ページ)で、STLコンテナーはその内容が「通常の」コピー動作を示す必要があるため、のコンテナーはauto_ptr許可されないことも述べました。
Qiang Xu

31

Herb SutterがGotW#89について説明しています

auto_ptrとの関係は何ですか?auto_ptrは、C ++が移動セマンティクスを持つ前に、unique_ptrを作成しようとする勇敢な試みとして最も魅力的に特徴付けられています。auto_ptrは非推奨になりました。新しいコードでは使用しないでください。

既存のコードベースにauto_ptrがある場合、機会があったら、auto_ptrからunique_ptrへのグローバルな検索と置換を試してください。大部分の用途は同じように機能し、(コンパイル時のエラーとして)発見したり、知らなかったバグを修正したり(サイレントに)したりする可能性があります。

言い換えると、グローバルな検索と置換はコードを一時的に「破壊」する可能性がありますが、とにかくそれを行う必要があります。コンパイルエラーを修正するのに少し時間がかかる場合がありますが、長期的にははるかに多くのトラブルを節約できます。


素晴らしいリンク。どうもありがとう!
fotNelton 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.