2012-03-10 3 views
2

std::vectorboost::ptr_vector이어야합니다. 관리를 쉽게하기 위해 boost :: ptr_vector를 클래스 (Zoo)에 넣고 std :: vector로 만들었습니다 (allZoos). 이 문제를 재현하기위한 최소한의 코드를보고 : (전체 오류 로그가 게시되지, 너무 오래했다)ptr_vector <an_abstract_class>가 포함 된 클래스의 벡터를 만들 수 없습니다

C2259: 'Animal' : cannot instantiate abstract class c:\boost_1_49_0\boost\ptr_container\clone_allocator.hpp 34 1 
:

#include <boost/ptr_container/ptr_vector.hpp> 
#include <boost/utility.hpp> 

class Animal 
{ 
public: 
    virtual char type() = 0; 
}; 

class Cat : public Animal 
{ 
public: 
    char type() { return 1; } 
}; 

class Zoo 
{ 
public: 
    boost::ptr_vector<Animal> animals; 
}; 


int main() 
{ 
    std::vector<Zoo> allZoos; 

    Zoo ourCityZoo; 
    ourCityZoo.animals.push_back(new Cat()); 

    //Uncommenting any of the lines below causes error: 
    //allZoos.push_back(ourCityZoo); 
    //allZoos.clear(); 

    return 0; 
} 

allZoos 괜찮 선언,하지만 멤버 함수를 호출하면 컴파일러 오류가 발생합니다

이것은 부스트의 복사 할 수없는 유틸리티 클래스와 사용자 정의 new_clone 함수와 아무런 관련이 없습니다. 어떻게 해결 될 수 있습니까?

(내가 VS2010를 사용하고 있습니다)

+0

가장 쉬운 해결책은 아마도'ptr_vector'를 버리고 대신'std :: vector >'를 사용하는 것입니다. – Xeo

+0

@ Xeo : 예, 지금은 임시 해결 방법을 사용하고 있습니다. 그러나 이후에'ptr_vector'가 그러한 템플릿을 대체하기 위해 만들어졌고 "작동"해야합니다! 나는 또한 왜 std :: vector >'가 단순히 작동하는지 궁금하지만 질문의 코드는 그렇지 않다. – Hossein

답변

9

사실, 오류가 도왔 것 나타나는 위치에 읽기. 부스트 소스에서 분명 명확하고 말했다 : 당신은 유형을 복제 할 수있는 방법을 지정하지 않으면

template< class T > 
inline T* new_clone(const T& r) 
{ 
    // 
    // @remark: if you get a compile-error here, 
    //   it is most likely because you did not 
    //   define new_clone(const T&) in the namespace 
    //   of T. 
    // 
    T* res = new T(r); 
    BOOST_ASSERT(typeid(r) == typeid(*res) && 
        "Default new_clone() sliced object!"); 
    return res; 
} 

것은 단순히 추상 클래스 가능하지 않은, 복사하여 그렇게하려고합니다. 네임 스페이스의 abstract_classnew_clone 함수에 적절한 clone 메서드를 추가하면 충분합니다.

Here 님의 코드가 고정 된 버전입니다.

+0

+1 : 나를 이길! – Johnsyweb

+0

감사합니다. 그래서 나는 어떻게 복제품을 사용할 지 몰랐다. 나는'ptr_vector'가 객체를 복제 할 필요가 없다고 생각했다. 그러나 를 읽은 후에는 많은 함수가 포함 된 객체를 복제하는 데 의존합니다. – Hossein