2016-05-29 23 views
2

私はというクラスから継承したDerivedというクラスを持っているとします。 Baseは特別です。新しいものを使用して作成することもできますが、カスタムのDeleterを使用して破棄する必要があります。派生クラスでカスタムディテッターでstd :: make_uniqueを使用していますか?

BaseDeleterというカスタムディレクターと一緒にをunique_ptrに追加したいと思います。これにより、Baseから派生した他のクラスを割り当てることもできます。そして、例外安全性と一貫性のために、私はunique_ptrをお尻にするためにstd::make_uniqueを使用したいと思います。

#include <memory> 

class Base 
{ 
}; 

class Derived : public Base 
{ 
}; 

struct BaseDeleter 
{ 
    void operator()(Base* base) 
    { 
     // Perform some special deleting 
    } 
}; 

class Big 
{ 
public: 
    Big() 
    { 
     //pointer.reset(new Derived()); // This works! 
     pointer = std::make_unique<Derived, BaseDeleter>(); // But this doesn't... 
    } 

private: 
    std::unique_ptr<Base, BaseDeleter> pointer; 
}; 

int main() 
{ 
    Big clazz; 
} 

は、残念ながら、これは両方のVisual Studio 2015のアップデート2とgcc-5.1でコンパイルに失敗します。

は、私が欲しいものを示している小さなスニペットを作成しました。 ( ideone
これはなぜ機能しませんか?どのように std::unique_ptrを割り当てるのに std::make_uniqueを使うことができますか?

答えて

2

これはmake_uniqueの署名(S)、私はあなたが使用されることを期待推測1(の1つ)です:Tが作成するオブジェクトの種類です

template< class T, class... Args > 
unique_ptr<T> make_unique( Args&&... args ); 

Args...コンストラクタに転送する引数の型です。

ご覧のとおり、スマートポインタのmake_*ヘルパー機能(make_uniquemake_sharedもない)を使用してカスタムの削除機能を指定することはできません。

あなたは、次のように明示的にポインタを構築する必要があります。

std::unique_ptr<T, D> ptr{new T{)}; 

を削除手段が構成可能デフォルトではない場合、あなたはこれを行うことができます:

dはデリータのインスタンスである
std::unique_ptr<T, D> ptr{new T{}, d}; 

2

ユニークにすることは、カスタムレターでは機能しません。あなた自身で書くか、それを使用しないでください。

これは、赤ちゃんであるあなたの質問のベース/導出合併症とは関係ありません。

関連する問題