56

ブースト ライブラリに C++1x の std::unique_ptr に相当するクラスはありますか? 私が探している動作は、例外セーフなファクトリ関数を持つことができることです...

std::unique_ptr<Base> create_base()
{
    return std::unique_ptr<Base>(new Derived);
}

void some_other_function()
{
    std::unique_ptr<Base> b = create_base();

    // Do some stuff with b that may or may not throw an exception...

    // Now b is destructed automagically.
}

編集:現在、私はこのハックを使用しています。これは、現時点で入手できる最高のようです...

Base* create_base()
{
    return new Derived;
}

void some_other_function()
{
    boost::scoped_ptr<Base> b = create_base();

    // Do some stuff with b that may or may not throw an exception...

    // Now b is deleted automagically.
}
4

5 に答える 5

71

unique_ptrC++0x なしでは (標準ライブラリの一部であるため、Boost はそれを提供する必要はありません) のようなものを作成することはできません。

具体的には、C++0x の機能である右辺値参照がunique_ptrなければ、Boost の有無にかかわらず、の堅牢な実装は不可能です。

C++03 では、いくつかの代替案が考えられますが、それぞれに欠点があります。

  • boost::shared_ptr機能の点では、おそらく最も簡単な代替品です。他の方法で使用する場所ならどこでも安全に使用でき、unique_ptr機能します。参照カウントが追加されるため、それほど効率的ではありません。しかし、できることすべてを処理できる単純なドロップイン代替品を探しているunique_ptrなら、これがおそらく最善の策です. (もちろん、 はshared_ptrさらに多くのことを行うことができますが、単純に のドロップイン置換として使用することもできますunique_ptr。)
  • boost::scoped_ptrに似てunique_ptrいますが、所有権の譲渡は許可されていません。スマート ポインターがその寿命を通じて排他的な所有権を保持することを意図している限り、これはうまく機能します。
  • std::auto_ptrと非常によく似た動作をしunique_ptrますが、いくつかの制限があります。主に、標準ライブラリ コンテナーに格納できないことです。所有権の譲渡を可能にするポインタを単に探しているが、コンテナに格納したりコピーしたりすることを意図していない場合、これはおそらく良い賭けです。
于 2010-06-01T22:36:51.853 に答える
38

Boost 1.57以降では、 Boost.Moveライブラリに公式のunique_ptr実装があります。

ドキュメントから:

(...) std::unique_ptr のドロップイン置換で、C++03 コンパイラからも使用できます。

コードは<boost/move/unique_ptr.hpp>ヘッダー ファイルで使用でき、boost::movelib名前空間に存在します。さらに、Boost.Move ライブラリは、名前空間でもmake_unique()ファクトリ関数を提供します。<boost/move/make_unique.hpp>boost::movelib

したがって、質問の例は次のように実装できます。

#include <boost/move/unique_ptr.hpp>

using boost::movelib::unique_ptr;

unique_ptr<Base> create_base()
{
    return unique_ptr<Base>(new Derived);
}

Wandbox で実際の例を参照してください。このコードは、C++98 モード (!) の gcc 4.6.4 で正常にコンパイルされることに注意してください。

基本/派生クラスを使用してケースに適用すると興味深いのはboost::movelib::unique_ptr、実装により、基本クラスでの仮想デストラクタの宣言に対するコンパイル時のチェックが提供されることです。これを省略した場合、コードはコンパイルされません([実行 (...)] ボタンをクリックして、コンパイラ エラー メッセージを表示します)。

マイナーな問題の 1 つは、インクルードはboost/moveディレクトリから取得されますが、コードはboost::movelib名前空間に存在することです (微妙な違いですが、煩わしい場合があります)。

詳細については、boost メーリング リストのスレッドも参照してください。

この非常にユニークで便利なコードを提供してくれた Ion Gaztañaga に感謝します。

于 2015-01-28T13:05:51.177 に答える
10

unique_ptr<>Howard Hinnant のC++03 向けの「概念実証」の実装を試してみてください(免責事項 - 私はまだ行っていません):

彼の例の 1 つは、次を返しますunique_ptr<int>

unique_ptr<int> factory(int i)
{
    return unique_ptr<int>(new int(i));
}
于 2010-06-01T22:56:01.573 に答える
5

インタープロセスライブラリunique_ptrからはどうですか?

于 2010-06-01T21:39:09.037 に答える
4

Howard Hinnant のunique_ptrを使用しました。コンパイラから異常なメタプログラミング エラーを読み取るのが苦手な場合は、回避することをお勧めします。ただし、90% のケースで unique_ptr と同じように動作します。

それ以外の場合は、パラメーターを as として渡しboost::scoped_ptr&、内部でスワップして所有権を盗むことをお勧めします。unique_ptr スタイルの戻り値を取得するには、auto_ptr. auto_ptror の戻り値をキャプチャして、 shared_ptrorscoped_ptrを直接使用しないようにしauto_ptrます。

于 2010-06-02T15:20:37.043 に答える