[prog] C++: storing objects of different type in a std::map

Riccarda Cassini riccarda.cassini at gmx.de
Tue Sep 21 02:33:18 EST 2004


Hi everyone,

I have some C++ code (written by someone else) which I need to clean up
for various reasons.  It would already help a lot if I could use some
data structure like Perl's hash tables, so I thought using std::map
would be the way to go.  The problem I'm currently facing is that, in
contrast to Perl's hashes, std::map seems to require a specific type
for the value of the key-value pairs...

There are various 'modes' the program operates in.  The modes have
names (i.e. strings) which are read from some input file.  Depending on
the mode, different objects/classes are used for handling functions
like update(), etc.  That's why I thought it would be nice to simply
have a dispatcher map to index the different handler objects by mode.

As long as I have a single class, everything works fine, as I can
specify its type in the map declaration, e.g.:

#include <string>
#include <iostream>
#include <map>
    
class ClassA
{
    public :
        ClassA(int num = 0) { id = num; }
        void update() {
            std::cout << "updating A (obj id=" << id << ")\n";
        }
    private:
        int id;
};

int main()
{
    std::map < std::string, ClassA > dispatch;
    // ClassA being the type of the values to hold
    
    ClassA a0, a1(1), a2(2);

    dispatch["mode-A"]   = a0;
    dispatch["mode-A-1"] = a1;
    dispatch["mode-A-2"] = a2;
    
    dispatch["mode-A"].update();
    dispatch["mode-A-1"].update();
    dispatch["mode-A-2"].update();
}

When I compile and run this I get:

updating A (obj id=0)
updating A (obj id=1)
updating A (obj id=2)

which is exactly what I need.  Problem is, I can't store objects of a
different type in the same map.  When I try to assign an object of
type ClassB, for example, I get a compilation error:

testmap.cpp: In function `int main()':
testmap.cpp:36: no match for `ClassA & = ClassB &'
testmap.cpp:14: candidates are: class ClassA & ClassA::operator =(const ClassA &)

OK, fine, makes sense.  Next, I thought that, maybe, adding some common
base class that all objects are derived from might help (specifying the
base class as the type to store in the map).  This is something I could
add to the existing source without too much fuss, as the classes are
rather similar, anyway.  So, I tried:

#include <string>
#include <iostream>
#include <map>
    
class baseClass
{
    public :
        virtual void update() = 0;
};


class ClassA : public baseClass
{
    public :
        ClassA(int num = 0) { id = num; }
        void update() {
            std::cout << "updating A (id=" << id << ")\n";
        }
    private:
        int id;
};

class ClassB : public baseClass
{
    public :
        void update() {
            std::cout << "updating B\n";
        }
};

int main()
{
    std::map < std::string, baseClass > dispatch;
    
    ClassA a0, a1(1), a2(2);
    ClassB b;

    dispatch["mode-A"]   = a0;
    dispatch["mode-A-1"] = a1;
    dispatch["mode-A-2"] = a2;
    dispatch["mode-B"]   = b;
    
    dispatch["mode-A"].update();
    dispatch["mode-A-1"].update();
    dispatch["mode-A-2"].update();
    dispatch["mode-B"].update();
}

Trying to compile this gives me a whole screen full of error messages,
in essence saying that what I'm trying to do isn't possible, as there
are virtual functions in baseClass...
When I supply some dummy implementation of update() in the base class,
it compiles fine, but then that function is always being called,
independently of which object types I store in the map, i.e. when I
rewrite the above baseClass definition as

class baseClass
{
    public :
        void update() {
            std::cout << "updating base\n";
        }
};

I see that this dummy function is being called all the time:

updating base
updating base
updating base
updating base

which is not what I need...

So, my question is, how would an experienced C++ programmer approach
the issue?  Would using templates help? If yes, how?
Please be gentle... I just started dabbling around in C++ :-)

Thanks,

Riccarda



More information about the Programming mailing list