web-dev-qa-db-ja.com

std :: auto_ptrからstd :: unique_ptr

新しい標準(および一部のコンパイラですでに利用可能な部分)が追加されたため、新しい型std::unique_ptrstd::auto_ptrの代わりとなるはずです。

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

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

180
Martin York

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_ptrdeleteを呼び出します。

211
Cubbi

std::auto_ptrstd::unique_ptrは、ある意味で互換性がなく、あるものでは置き換えが低下しています。そのため、検索/置換は十分ではありません。ただし、検索/置換でコンパイルエラーを処理すると、奇妙なコーナーケースを除くすべてが修正されます。ほとんどのコンパイルエラーでは、std::moveを追加する必要があります。

  • 関数スコープ変数:
    100%互換性があります。値で別の関数に渡さない限り。
  • 戻り値のタイプ:
    100%互換ではありませんが、99%互換ではないようです。
  • 値による関数パラメーター:
    1つの警告と100%互換性があります。unique_ptrsはstd::move呼び出しで渡す必要があります。これは、コンパイラーが正しくないと文句を言うので簡単です。
  • 参照による関数パラメーター:
    100%互換。
  • クラスメンバー変数:
    これは注意が必要です。 std::auto_ptrsのコピーセマンティクスは悪です。クラスがコピーを許可しない場合、std::unique_ptrは置き換えのドロップです。ただし、クラスに適切なコピーセマンティクスを与えようとした場合は、std::auto_ptr処理コードを変更する必要があります。これは単純です。正しくない場合、コンパイラは文句を言うでしょう。 std::auto_ptrメンバーなしで特別なコードを使用してクラスのコピーを許可した場合は、ご不便をおかけして幸運を祈ります。

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

88
deft_code

知る限り、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には完全に新しい機能が追加され、コンテナに保存できるようになります。

33
UncleBens

Herb Sutterには GotW#89 についての素敵な説明があります:

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

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

言い換えれば、グローバルな検索と置換はコードを一時的に「破壊」する可能性がありますが、とにかくそれを行う必要があります。

27
ValarDohaeris