2016-11-02 5 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의 소멸자를 호출해야한다는 것을 알고 있습니다. 각 서브 클래스가 할당 한 메모리를 삭제하지 않은 상태로 남겨 두었다.

각 개체의 메모리를 올바르게 형 변환하고 해제하는 방법을 알 수 있도록 사용자 지정 삭제자를 스마트 포인터에 전달하는 방법은 무엇입니까? 그 커스텀 Deleter를 어떻게 구현해야합니까?

+0

커스텀 Deleter 대신에'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.

관련 문제