新しい標準(および一部のコンパイラですでに利用可能な部分)が追加されたため、新しい型std::unique_ptr
はstd::auto_ptr
の代わりとなるはずです。
それらの使用法は正確に重複していますか(したがって、コードでグローバルな検索/置換を行うことができます(これを行うのではなく、私がした場合))、またはドキュメントを読んでも明らかではないいくつかの違いに注意する必要がありますか?
また、直接の置換である場合、単にstd::auto_ptr
を改良するのではなく、新しい名前を付けるのはなぜですか?
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
を呼び出します。
std::auto_ptr
とstd::unique_ptr
は、ある意味で互換性がなく、あるものでは置き換えが低下しています。そのため、検索/置換は十分ではありません。ただし、検索/置換でコンパイルエラーを処理すると、奇妙なコーナーケースを除くすべてが修正されます。ほとんどのコンパイルエラーでは、std::move
を追加する必要があります。
unique_ptr
sはstd::move
呼び出しで渡す必要があります。これは、コンパイラーが正しくないと文句を言うので簡単です。std::auto_ptr
sのコピーセマンティクスは悪です。クラスがコピーを許可しない場合、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
の奇妙な動作に依存している場合は、とにかくコードをリファクタリングする必要があります。
知る限り、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
には完全に新しい機能が追加され、コンテナに保存できるようになります。
Herb Sutterには GotW#89 についての素敵な説明があります:
auto_ptrとの関係は何ですか?auto_ptrは、C++がセマンティクスを移動する前にunique_ptrを作成しようとする勇敢な試みとして最も慈善的に特徴付けられています。 auto_ptrは非推奨になったため、新しいコードでは使用しないでください。
既存のコードベースにauto_ptrがある場合は、機会があればauto_ptrをunique_ptrにグローバルに検索および置換してみてください。使用の大部分は同じように機能し、知らなかった1つまたは2つのバグを公開(コンパイル時エラーとして)または修正(サイレント)する可能性があります。
言い換えれば、グローバルな検索と置換はコードを一時的に「破壊」する可能性がありますが、とにかくそれを行う必要があります。