问题
I need to have a std::vector
of boost::ptr_vector
s. To make their management easier, I enclosed the boost::ptr_vector in a class (Zoo
) and made a std::vector of it (allZoos
). Look at a minimal code for reproducing this:
#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;
}
Declaring allZoos
is okay, but calling any of its member functions causes the compiler error: (The full error log was so long, not posted)
C2259: 'Animal' : cannot instantiate abstract class c:\boost_1_49_0\boost\ptr_container\clone_allocator.hpp 34 1
This had nothing to do with boost's noncopyable utility class and custom new_clone
functions and I tried them with no luck. How can that be solved?
(I'm using VS2010)
回答1:
Actually, reading into where the error appears would've helped. It's stated clear and plainly in the Boost source:
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;
}
If you don't specify a way to clone the type, it will try to do so by simply copying it, which isn't possible with abstract classes. Add an appropriate clone
method to the abstract_class
and a new_clone
function in its namespace and you'll be fine.
Here's a fixed version of your code.
来源:https://stackoverflow.com/questions/9645090/cant-make-a-vector-of-a-class-containing-a-ptr-vectoran-abstract-class