Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::map unable to handle polymorphism?

Tags:

c++

When using std::map in c++, is it possible to store inherited classes as their "base class" in the map and still being able to call their overloaded methods? See this example:

#include <iostream>
#include <map>
class Base
{
    public:
    virtual void Foo() { std::cout << "1"; }
};

class Child : public Base
{
    public:
    void Foo() { std::cout << "2"; }
};

int main (int argc, char * const argv[])
{
    std::map<std:string, Base> Storage;
    Storage["rawr"]=Child();
    Storage["rawr"].Foo();
    return 0;
}

This following code writes "1". Which somehow tells me that polymorphism doesn't work when you use std::map.

like image 329
Filip Ekberg Avatar asked May 07 '09 07:05

Filip Ekberg


2 Answers

Polymorphism doesn't work in that case because the std::map stores the Base as a value type, so the objects get sliced.

If you want to have polymorphism on stored objects, you need to store pointers or use one of the boost ptr containers to effect the same. This means you need to remember to delete the memory afterwards (please don't put pointers to stack objects into the map)

like image 75
workmad3 Avatar answered Sep 24 '22 03:09

workmad3


Its case of Object Slicing. Try to insert with pointers.

In the presence of inheritance copying leads to slicing. That is, if you create a map of base class objects and you try to insert derived class objects into it, the derivedness of the objects will be removed as the objects are copied (via the base class copy constructor) into the map.

Hence, it is recommended to use pointers rather than copies itself.

like image 27
aJ. Avatar answered Sep 23 '22 03:09

aJ.