views:

175

answers:

2

My C++ is a bit rusty. Here's what I'm attempting to do:

class Cmd { };
class CmdA : public Cmd { };
class CmdB : public Cmd { };
...
Cmd *a = new CmdA ();
Cmd *b = new CmdB ();

First problem:

cout << typeid (a).name ()
cout << typeid (b).name ()

both return Cmd * types. My desired result is CmdA* and CmdB*. Any way of accomplishing this other than:

if (dynamic_cast <CmdA *> (a)) ...

Second, I would like to do something like this:

class Target {
    public:
        void handleCommand (Cmd *c) { cout << "generic command..." }
        void handleCommand (CmdA *a) { cout << "Cmd A"; }
        void handleCommand (CmdB *b) { cout << "Cmd B"; }
};

Target t;
t.handleCommand (a);
t.handleCommand (b);

and get the output "Cmd A" and "Cmd B". Right now it prints out "generic command..." twice.

Thanks

+1  A: 

Looks like you are after double/multi dispatch... take a look at here for some info for hacking it into C++. Also take a look at the Visitor pattern.

I think what you would essentially want to do is the dynamic cast to figure out the type and then a static cast to call the appropriate handle command. That being said my C++ is rusty too :-)

TofuBeer
+4  A: 

Ah but typeid(a).name() will be Cmd* because its defined as Cmd*. typeid(*a).name() should return CmdA

http://en.wikipedia.org/wiki/Typeid

Also, the base class of whatever you pass to typeid must have virtual functions, otherwise you get back the base class.

MSDN has a more eloquent explanation for that:

If the expression points to a base class type, yet the object is actually of a type derived from that base class, a type_info reference for the derived class is the result. The expression must point to a polymorphic type (a class with virtual functions). Otherwise, the result is the type_info for the static class referred to in the expression. Further, the pointer must be dereferenced so that the object it points to is used. Without dereferencing the pointer, the result will be the type_info for the pointer, not what it points to.

Igor Zevaka
Ahh yes. Another thing I was missing was having at least one virtual function in Cmd. virtual ~Cmd () {}
Shaun