Не удается создать вектор из класса, содержащего ptr_vector <an_abstract_class> - PullRequest
2 голосов
/ 10 марта 2012

Мне нужно иметь std::vector из boost::ptr_vector с. Чтобы упростить их управление, я вложил в класс boost :: ptr_vector (Zoo) и создал из него std :: vector (allZoos). Посмотрите на минимальный код для воспроизведения этого:

#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 нормально, но вызов любой из его функций-членов вызывает ошибку компилятора: (Полный журнал ошибок был очень длинным, не опубликован)

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

Это не имело никакого отношения к не копируемому служебному классу boost и пользовательским new_clone функциям, и я попробовал их без удачи. Как это можно решить?

(я использую VS2010)

1 Ответ

9 голосов
/ 10 марта 2012

На самом деле, чтение того, где появляется ошибка, помогло бы. Это ясно и ясно указано в источнике Boost:

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;
}

Если вы не укажете способ клонирования типа, он попытается сделать это, просто скопировав его, что невозможно для абстрактных классов. Добавьте соответствующий метод clone к функции abstract_class и new_clone в его пространстве имен, и все будет в порядке.

Здесь - это фиксированная версия вашего кода.

...