[prog] C++: storing objects of different type in a std::map
Kathryn Hogg
kjh at flyballdogs.com
Mon Sep 20 20:22:49 EST 2004
Riccarda Cassini said:
> 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).
Yep, that is the correct path to take.
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;
> };
Looks good.
>
>
> 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";
> }
> };
Looks good here too.
> int main()
> {
> std::map < std::string, baseClass > dispatch;
Ok, here's the problem. The compiler is complaining because you can't
instantiate objects of type baseClass because of the pure virtual function
update.
And before you take take the "=0" off the the declaration, you should
realize that the compiler did a very good thing.
If you could use a baseClass, thats all you will have in the map. Any
object of a derived class will be downgraded/truncated to its base class
component.
What you want to do is store an object that can be of type baseClass or
any of its descendents. C++ provides two constructs for this: pointers
and references.
The simplest methos would be to change the map to
std::map<std::string, baseClass *> dispatch;
and then allocate heap objects to put in the map.
>
> ClassA a0, a1(1), a2(2);
> ClassB b;
>
> dispatch["mode-A"] = a0;
dispatch["mode-A"] - new ClassA;
> dispatch["mode-A-1"] = a1;
dispatch["mode-A-1"] = new ClassA(1);
> 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();
> }
> 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
Correct as I explained above, when you insert objects into the map, you
are storing objects of exactly type baseClass.
>
> class baseClass
> {
> public :
> void update() {
> std::cout << "updating base\n";
> }
> };
You would still have wanted "virtual void update()" if you intended to
override the implementation in derived classes.
> 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++
The way you attempted to go about it is reasonable.
--
Kathryn
http://womensfooty.com
More information about the Programming
mailing list