2017-02-15 4 views
1

추상 기본 클래스 (ABC)의 구체적인 인스턴스에 대한 원시 포인터 벡터의 수명을 수동으로 처리하는 일부 오래된 코드를 다시 작성했습니다. 방법/벡터 <unique_ptr <ABC>>을 가질 수 있습니까?

그래서 벡터의 소유자가 직접 겪은과 벡터의 내용을 삭제 가상 dtor 등 벡터의 소유자가의 요소를 소유하고 있기 때문에

했다, 그것은 많은 의미가 변경할 수 있습니다 unique_ptr의 벡터.

슬프게도 이것이 불가능한 것 같습니까? vector<unique_ptr<type>>type에 대한 정적 dtor을 할 수 있어야하지만 때문에이 경우 유형에 ABC이기 때문에, 즉, 따라서 vector이 ...

를 컴파일되지 않습니다 아니면 내가 뭔가를 놓친 거지 사용할 수 없습니다?

예 :

struct ABC 
{ 
    ABC() = default; 
    virtual ~ABC() { } // need a vtable entry so that concrete subclasses will be deleted through the base dtor 

    virtual std::unique_ptr<ABC> Clone() = 0; 
    virtual void Foo() = 0; 

    std::vector<std::unique_ptr<ABC>> elements; 
}; 

EDIT2 : 당신이 Base의 인스턴스 또는 Base에서 파생 된 형식의 인스턴스를 복사 할 때

#include <iostream> 
#include <memory> 
#include <vector> 

struct ABC 
{ 
    virtual ~ABC() { } // need a vtable entry so that concrete subclasses will be deleted through the base dtor 

    virtual std::unique_ptr<ABC> Clone() = 0; 
    virtual void Foo() = 0; 

    std::vector<std::unique_ptr<ABC>> elements; 
}; 

struct Child : ABC 
{ 
    std::unique_ptr<ABC> Clone() override { return std::make_unique<Child>(*this); } 
    void Foo() override { }; 
}; 

struct Derived : Child 
{ 
    std::unique_ptr<ABC> Clone() override { return std::make_unique<Derived>(*this); } 
}; 

int main() 
{ 
    std::unique_ptr<ABC> x; 
    std::unique_ptr<ABC> c = std::make_unique<Child>(); 

    std::vector<std::unique_ptr<ABC>> elements; 
    elements.emplace_back(std::make_unique<Derived>()); 
    return 0; 
} 
+0

확실하지하지만 당신은 문제의 예제 코드에서 같은 이름을 사용하는 경우 그것은 당신이 많은 명확하게 무엇을 요구한다 : 완성도를 위해서 – NathanOliver

+0

기지를 전달할 수 없습니까? 정의하기 바로 전에? –

+0

VS 2015 Upd 3에서 기본적으로 메시지의 기본 세트를 가져 오지 않습니다. Base의 삭제 관리자 (아마도 ABC이기 때문입니다) – Mordachai

답변

4

오류가 발생합니다 : 여기에 실패 완벽한 예입니다 . 기본 복사 생성자는 Base::elements을 복사하여 각 요소를 새로운 vector에 복사하려고 시도합니다. 이 요소는 unique_ptr<Base>이므로이 사본을 사용할 수 없습니다.

#include <memory> 
#include <vector> 

struct Base 
{ 
    using PBase = std::unique_ptr<Base>; 
    using VBase = std::vector<PBase>; 

    VBase elements; 
}; 

int main() 
{ 
    Base x; 
    auto y = x; // This line causes the error 

    return 0; 
} 

당신은 아마 당신의 자신의 복사 생성자를 구현해야하고 대입 연산자를 복사하거나이 기능을 삭제하여 복사를 금지합니다

이 예제에서는 문제가 재생하기. 얕은 복사본이 응용 프로그램에서 작동하는 경우 shared_ptr을 대신 사용하십시오. 모든 사람에 대해 다른

class ABC 
{ 
public: 
    ABC() = default; 
    ABC(const ABC & rhs) 
    { 
     // manually clone our elements 
     elements.reserve(rhs.elements.size()); 
     for (const auto & e : rhs.elements) 
      elements.emplace_back(e->Clone()); 
    } 
    ABC & operator = (const ABC &) = delete; 

    virtual ~ABC() { } // need a vtable entry so that concrete subclasses will be deleted through the base dtor 

    virtual std::unique_ptr<ABC> Clone() = 0; 
    virtual void Foo() = 0; 

    std::vector<std::unique_ptr<ABC>> elements; 
}; 
+0

감사. 나는 단지 명백한 것을 보지 않고 있었다. 감사합니다. – Mordachai

0

, 여기에 내가 뭘 했어야 무엇 . 즉, 오류는 무엇입니까? 귀하의 예제 코드는 나를 위해 컴파일됩니다.
관련 문제