Thread: boost::ptr_map instantiating virtual base class

  1. #1
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937

    boost::ptr_map instantiating virtual base class

    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?
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Like std::map, it's operator[] requires that the stored type is default constructible. If you know the key is there, you might be able to use find, which doesn't (potentially) insert new items.

    Code:
    todo_list.push_back( clone_zoo.find(circle_name)->second.create(intargs, colorargs) );  //or something like that
    Better make that a separate functions that also checks whether the key was found.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    I see. shared_ptr it is.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Some Interview questions, please help
    By higaea in forum C++ Programming
    Replies: 5
    Last Post: 03-29-2010, 06:35 AM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Replies: 3
    Last Post: 10-27-2006, 12:33 AM
  4. abstract class
    By xddxogm3 in forum C++ Programming
    Replies: 5
    Last Post: 01-01-2005, 09:08 AM
  5. virtual function in base class
    By QueSue in forum C++ Programming
    Replies: 12
    Last Post: 01-25-2003, 05:27 PM