I have been writing an event class for my game engine and I came across to the following problem:
Is casting a base class object to a derived class object given a type flag a good programming design?
Let me give you the following simple example. I have this enum
holding the categories of the events:
enum DisplayEventType
{
DET_UNSET,
DET_WINDOW_EVENT,
DET_KEYBOARD_EVENT,
DET_MOUSE_EVENT,
DET_JOYSTICK_EVENT
};
This is the base class of all the events:
typedef std::unique_ptr<DisplayEventData> DisplayEventDataMP;
class DisplayEvent
{
private:
// The type of the display event
DisplayEventType mType;
// The data of the event
DisplayEventDataMP mEventData;
public:
// Constructor
DisplayEvent(DisplayEventType type = DisplayEventType::DET_UNSET, DisplayEventDataMP eventData = std::unique_ptr<DisplayEventData>((DisplayEventData*) 0));
// Retrieves the event type of the current event
DisplayEventType GetType() const;
// Sets the event type of the current event
void SetType(DisplayEventType type);
// Retrieves a raw pointer to the event data of the current event
DisplayEventData* GetEventData() const;
// Sets the event data of the current event
void SetEventData(DisplayEventDataMP eventData);
};
This is the base class of the event data:
class DisplayEventData
{
public:
// Virtual destructor, for the deallocation of the interface implementors to work
virtual ~DisplayEventData();
};
And these are the derived classes
class WindowEventData : public DisplayEventData
{
// Window event data specific data and methods
};
class KeyboardEventData : public DisplayEventData
{
// Keyboard event data specific data and methods
};
class MouseEventData : public DisplayEventData
{
// Mouse event data specific data and methods
};
class JoystickEventData : public DisplayEventData
{
// Joystick event specific data and methods
};
Some basic usage would be this:
// Poll for next event in the queue
DisplayEvent ev;
display->PollEvent(ev); // Fills ev with the needed data
if (ev.GetType() == DisplayEventType::DET_KEYBOARD_EVENT)
{
KeyboardEventData* kev = static_cast<KeyboardEventData>(ev.GetEventData());
// Do stuff
}
Is the above design viable/correct? If not what would a better alternative be in terms of object oriented or even generic programming?