2016-11-02 8 views
1

std::listに大量のオブジェクトを格納しようとしています。スマートポインタと派生クラス

さまざまな種類のデータを格納するオブジェクトが必要なので、派生クラスのどのオブジェクトにキャストするかを示すenum型の属性を保持する基本クラスへのポインタを格納します。各派生クラスは、データの独自のタイプがあります。各ベースオブジェクトは、それがどうあるべきかを入力知っていながら、しかし

std::list<std::unique_ptr<Base>> list; 
list.push_back(std::unique_ptr<Base>(new D1("Somestring"))); 
list.push_back(std::unique_ptr<Base>(new D2(3.14))); 

:これらのオブジェクトへのポインタを保持するために

struct Base { 
    enum class Type { 
     D1, 
     D2, 
     ... 
    } type; 

    Base(Type new_type): 
     type(new_type) {} 
}; 

struct D1: public Base { 
    std::string data; 

    D1(std::string new_data): 
     Base(Base::Type::D1), data(new_data) {} 
}; 

struct D2: public Base { 
    double data; 

    D2(double new_data): 
     Base(Base::Type::D2), data(new_data) {} 
}; 

を、私はスマートポインタを使用していますキャストされて正しく削除された場合、スマートポインタはBaseのデストラクタを呼び出さなければならないことしか知らない。各サブクラスに割り当てられたメモリを削除しないままにします。

カスタムオブジェクトをスマートポインタに渡して、各オブジェクトのメモリを適切にキャストして解放する方法を知るにはどうすればよいですか?私はそのカスタムデリゲーターを実装する必要がありますか?

+0

カスタムデリターではなく、 'Base'の' virtual'デストラクタはどうですか? –

答えて

6

Baseのデストラクタにvirtualとマークを付けるだけです。次に、デフォルトのDeleterがdelete pointer_to_raw_object;を呼び出し、動的タイプobjectに基づいて正しいデストラクタを呼び出します。

例:

#include <iostream> 
#include <memory> 
#include <list> 

struct Base 
{ 
    virtual ~Base(){std::cout << __PRETTY_FUNCTION__ << std::endl;} 
}; 

struct Derived : Base 
{ 
    ~Derived() override {std::cout << __PRETTY_FUNCTION__ << std::endl;} 
}; 

int main() 
{ 
    std::list<std::unique_ptr<Base>> l; 
    l.emplace_back(new Base); 
    l.emplace_back(new Derived); 
} 

Live on Coliru

PS:クリーナー(及びより効率的な)のためstd::list::emplace_backを使用することを検討してコード。