2012-01-30 17 views
8

不完全な型で動作する非共有ポインタである標準的なポインタクラス(またはブースト)はありますか?私はC++ 11標準とブーストライブラリを使い、見つけられませんでしたが、非常に便利なタイプのようです。不完全な型の非共有スマートポインタ

例えば、私はスマートポインタを使って不透明な型を作りたいと思っています。

class A; 
    wrap_ptr<A> some_func(); 
    void other_func(A const &); 

Aは、様々な機能に使用できる不透明タイプです。上記のインターフェースのユーザーは、Aの不完全な定義のみを持ちますが、ポインターを削除/リセットできるはずです。私は上記のことがshared_ptrでできることを知っていますが、それは私がこの特定のコードで望ましくないオーバーヘッドを持っています。 unique_ptrは正しい所有権セマンティクスを持っていますが、不完全な型では動作しません。理論的には、ラッパーは、デリゲーターへのポインターを持つオーバーヘッドだけを必要とします。

C++ 11や追加ライブラリにこのようなタイプがありますか?

注:このタイプは簡単に作成できますが、できるだけ標準タイプを選択したいと思います。それは基本的なスマートなポインタタイプでなければならないようです。


UPDATEunique_ptr良い選択肢では表示されません。最初に構文のオーバーヘッドが相殺されるでしょう。第二に、私はそれがカスタムディレターで安全に使用できると確信していません。どのように動作するかを確認します。

答えて

4

実際には、unique_ptrは、カスタムディテクタを指定する限り、不完全な型でも動作します。

しかし、shared_ptrとは異なり、カスタムデリターは静的に(2番目のテンプレートパラメーターとして)事前定義されているため、実際にはその型に影響します。

+0

技術的には真ですが、これを直接使用するのは構文的に不愉快です。単純に 'ptr_type(new T)'を行うことはできませんが、テンプレートtypedefが正しいと仮定した場合、 'ptr_type(new T、T ::〜T)'を実行する必要があります。 –

+1

実際には、 'unique_ptr'を注意深く見ても、状態付きのカスタムデリターは使用できません。 'reset'関数は、コンストラクタだけが行うので、' unique_ptr'のカスタム削除の側面は部分的に壊れています。 –

+0

カスタムディレクターは必要ありません。型は 'unique_ptr'のデストラクタが呼び出されるときに完全である必要があります。つまり、保持されたクラスが完了した後にデストラクタを定義することができます。 – Xeo

1

std::unique_ptrこのケースは処理できますが、デフォルトのDeleterでは処理できません。あなたは、不完全な型を扱うことができるディレクターを書く必要がありますし、std::unique_ptr<A,MyDeleter>を使用してください。あなたがそのようなクラスのヘッダにそれを使用する場合、それは不完全な型で動作しますが、::

#include <memory> 

class A; 

class B 
{ 

std::unique_ptr<A> m_a; 

}; 

それが見つからないためデリータの実装をリンクしませんunique_ptrをを明確にすることが

9

。 これは簡単に修正できます:ホストクラスのデストラクタを空にするか、デフォルトのものにしても、cppで定義するだけです!

また
// B.hpp 
#include <memory> 

class A; 

class B 
{ 
public: 

    B(); 
    ~B(); 

private: 

std::unique_ptr<A> m_a; 

}; 

// B.cpp 

B::B(){} // or =default; (if you have a compiler providing it) 
B::~B(){} // or =default; (if you have a compiler providing it) 

、そこに私の質問への答えを読む:http://herbsutter.com/gotw/_100/

:ハーブサッターによってimplmentedすることが推奨される方法をPIMPLイディオム(unique_ptrを中uncompleteタイプを意味している)を見てみましょう Is std::unique_ptr<T> required to know the full definition of T?

そしておそらく

+1

これは私が欲しいものではありません。呼び出し側が完全な型を決して見ない場所で、関数の戻り値にポインタを使用したいと思います。 –

関連する問題