I think I might be misusing ptr_map. We'll see. I want to avoid the visual headache of shared_ptr<base> everywhere.
Here's some scaled-down problematic code. First what I'm doing, and then what boost:tr_map is doing.
Code:
/usr/local/include/boost/ptr_container/ptr_map_adapter.hpp|213|error: cannot allocate an object of abstract type ‘drawing’
Code:
typedef unsigned int color_t;
class drawing
{
public:
class bad_argument {};
drawing(int n_int_args_in, int n_color_args_in) : n_int_args(n_int_args_in), n_color_args(n_color_args_in) {}
virtual void draw(BMP & bitmap) = 0;
virtual drawing* create(const std::vector<int> & int_args, const std::vector<color_t> & color_args) = 0;
virtual ~drawing() {}
protected:
const unsigned int n_int_args;
const unsigned int n_color_args;
};
class circle : public drawing
{
public:
circle() : drawing(3,1) {}
circle(const std::vector<int> & int_args, const std::vector<color_t> & color_args)
: drawing(3,1)
{
// . . .
}
void draw(BMP & bitmap);
circle* create(const std::vector<int> & int_args, const std::vector<unsigned int> & color_args)
{
return new circle(int_args, color_args);
}
protected:
unsigned int radius;
unsigned int centerx;
unsigned int centery;
color_t color;
};
In main()...
Code:
boost::ptr_map< std::string, drawing > clone_zoo;
boost::ptr_vector<drawing> todo_list;
std::string circle_name = "circle";
clone_zoo.insert(circle_name, new circle());
std::vector<int> intargs;
intargs.push_back(5); intargs.push_back(7); intargs.push_back(2);
std::vector<color_t> colorargs;
colorargs.push_back(0xFFAA33);
todo_list.push_back( clone_zoo[circle_name].create(intargs, colorargs) );
And here is what happens in the map:
Code:
mapped_reference operator[]( const key_type& key )
{
return insert_lookup( key );
}
// . . .
mapped_reference insert_lookup( const key_type& key )
{
void*& ref = this->base()[key];
if( ref )
{
return *static_cast<mapped_type>(ref);
}
else
{
eraser e(&this->base(),key); // nothrow
mapped_type res = new T(); // strong
ref = res; // nothrow
e.release(); // nothrow
return *res;
}
}
So I guess that the reference-ness of the ptr_map is not allowing me to avoid instantiating the base class? Or have I done something wrong?