web-dev-qa-db-ja.com

unique_ptrブースト相当?

Boostライブラリに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.
}
54
Clark Gaebel

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

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

C++ 03には、いくつかの選択肢がありますが、それぞれに欠点があります。

  • boost::shared_ptrは、おそらく機能に関して最も単純な代替品です。それ以外の場合はunique_ptrを使用すればどこでも安全に使用でき、機能します。参照カウントが追加されているため、それほど効率的ではありません。ただし、unique_ptrが実行できるすべてを処理できる簡単なドロップイン置換を探している場合は、おそらくこれが最善の方法です。 (もちろん、shared_ptrはさらに多くのことを実行できますが、unique_ptrのドロップイン置換として単純に使用することもできます。)
  • boost::scoped_ptrunique_ptrに似ていますが、所有権の譲渡を許可しません。スマートポインターが、そのライフタイムを通じて排他的所有権を保持することを意図している限り、それは素晴らしい働きをします。
  • std::auto_ptrunique_ptrと非常によく似た動作をしますが、いくつかの制限があります。主に、標準ライブラリコンテナに格納できないということです。所有権の移動を許可するが、コンテナに保存したりコピーしたりすることを意図していないポインターを単に探している場合、これはおそらく良い方法です。
68
jalf

Boost 1.57 から始まる Boost.Move ライブラリには、公式の_unique_ptr_実装があります。

ドキュメント から:

(...)C++ 03コンパイラからも使用可能なstd :: unique_ptrのドロップイン置換。

コードは_<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_名前空間に存在します(微妙な違いですが、迷惑な場合があります)。

ブーストメーリングリストのスレッド も参照してください。

IonGaztañagaには、この絶対にユニークで有用なコードを提供してくれました。

33
Adam Romanek

Howard HinnantのC++ 03の「概念実証」unique_ptr<>実装を試してみることをお勧めします(免責事項-私はしていません):

彼の例の1つはunique_ptr<int>を返すことです:

unique_ptr<int> factory(int i)
{
    return unique_ptr<int>(new int(i));
}
10
Michael Burr

unique_ptrプロセス間 ライブラリから?

5
fbrereto

Howard Hinnantの nique_ptr を使用しました。コンパイラから狂ったメタプログラミングエラーを読むのがあまり得意でない場合は、明確にしたいかもしれません。ただし、90%のケースでunique_ptrのように機能します。

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

4
deft_code