1

I'm writing an event-based messaging system to be used between the various singleton managers in my game project. Every manager type (InputManager, AudioManager, etc) is derived from a base Manager class and also inherits from an EventHandler class to facilitate message processing, as follows:

class Manager
{ ... }

class EventHandler
{ ...
    virtual void onEvent(Event& e) =0;
  ...
}

class InputManager : public Manager, public EventHandler
{ ... 
    virtual void InputManager::onEvent(Event& e);
    { ... }
}

Elsewhere I have an EventManager that keeps track of all EventHandlers and is used for broadcasting events to multiple recievers.

class EventManager
{...
    addHandlerToGroup(EventHandler& eh);
    { ... } 
 ...
}

Naturally when I'm initializing all of my singleton Managers, I want to be adding them as they're created to the EventManager's list. My problem is that MVC++ complains at compile-time (and as I'm coding with squiggly lines) whenever I attempt to cast my Managers to EventHandlers. I thought it would work as follows:

int main()
{ ...
    EventManager* eventM = new EventManager();

    ...

    InputManager* inputM = new InputManager();
    eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));

} 

The compiler, however, informs me that "a cast to abstract class is not allowed." I was under the impression that you can...after all, polymorphism doesn't do you much good without passing objects back and forth with a bit of flexibility as to how close to the base class they are interpreted. My current workaround looks like this:

int main()
{ ...
    EventManager* eventM = new EventManager();
    EventHandler* temp;

    ...

    InputManager* inputM = new InputManager();
    temp = inputM;
    eventM->addHandlerToGroup(*inputM);

} 

Which, as far as I can tell, is the same conceptually for what I'm trying to accomplish, if a bit more verbose and less intuitive. Am I completely off as far as how typecasting with polymorphism works? Where am I going wrong?

ketura
  • 399
  • 1
  • 6
  • 11
  • Take a look at [this way of "interfaces" in C++](http://stackoverflow.com/questions/318064/how-do-you-declare-an-interface-in-c) – ZagNut Dec 24 '11 at 02:38
  • 1
    "`dynamic_cast(inputM));`" why `dynamic_cast`? – curiousguy Dec 24 '11 at 04:17
  • @curiousguy To be honest that was the last of the various casts I had tried. Since I'm going from derived to base, conceptually, I figured static_cast is what I would use; when that didn't work, I cycled through the other typecasts in desperation. – ketura Dec 25 '11 at 04:28
  • @user888539 This line doesn't make sense actually: `EventHandler` is a class type, so `dynamic_cast` isn't even possible. Also, `inputM` is actually `new InputManager()`, so it is a pointer, there is no dereference here, and you end with a reference to `EventHandler&`. Please post real minimal code. "_I figured static_cast is what I would use; when that didn't work,_" with which error message? "_I cycled through the other typecasts in desperation._" Don't do things "in desperation". Ask! – curiousguy Dec 25 '11 at 13:50
  • @curiousguy oh, I missed a *. That should read `dynamic_cast< EventHandler* >` . And as for what error I was getting, it was the same as above: I was being told "a cast to abstract class is not allowed", regardless of what cast I was using, which lead me here after I couldn't figure out where my typecasting was going wrong. As davogotland pointed out, it wasn't even that, but the fact that I was using references instead of pointers (I think). Come to think of it, this typo is why david answered the way he did, too. – ketura Dec 25 '11 at 22:12
  • I should clarify that was just a typo in me retyping and copy/pasting, it's not in the original code. At any rate, the issue was resolved, but I do thank you for your time. – ketura Dec 25 '11 at 22:13
  • @user888539 "_the fact that I was using references instead of pointers (I think)_" Actually, you can cast to a reference! – curiousguy Dec 25 '11 at 22:32

2 Answers2

4

in EventManager, declare the method addHandlerToGroup as

void addHandlerToGroup(EventHandler* handler);

then, just remove the cast. pass the pointer (in the example inputM) as it is to the addHandler method, and you should be fine :)

davogotland
  • 2,718
  • 1
  • 15
  • 19
  • I'll be darned. Well, no wonder I wasn't finding the answer on the interwebs; I was searching for polymorphism and typecasting lore, and it was a hangup on */&. Right when I thought I had that down, too. Thanks a bunch! – ketura Dec 24 '11 at 03:01
4
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));

I think you just lost track of what you were doing. In this code, inputM is an InputManager* and you are trying to cast it to an EventHandler. That is, you are trying to cast a pointer to one class to an instance of another class. That, of course, makes no sense.

You can cast a pointer to an instance of a derived class to a pointer to an instance of one of its base classes. I think that's what you meant to do.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Thanks for the clarification. When it all comes down to it, the problems always my understanding of pointers -_- – ketura Dec 24 '11 at 03:03