C++ Storing variables and inheritance
Here is my situation:
I have an event driven system, where all my handlers are derived from IHandler
class, and implement an onEvent(const Event &event)
method. Now, Event is a base class for all events and contains only the enumerated event type. All actual events are derived from it, including the EventKey
event, which has 2 fields: (uchar) keyCode
and (bool) isDown
.
Here's the interesting part: I generate an EventKey
event using the following syntax:
Event evt = EventKey(15, true);
and I ship it to the handlers:
E开发者_C百科ventDispatch::sendEvent(evt); // void EventDispatch::sendEvent(const Event &event);
(EventDispatch
contains a linked list of IHandlers
and calls their onEvent(const Event &event)
method with the parameter containing the sent event.
Now the actual question:
Say I want my handlers to poll the events in a queue of type Event
, how do I do that?
Dynamic pointers with reference counting sound like too big of a solution.
Making copies is more difficult than it sounds, since I'm only receiving a reference to a base type, therefore each time I would need to check the type of event, upcast to
EventKey
and then make a copy to store in a queue. Sounds like the only solution - but is unpleasant since I would need to know every single type of event and would have to check that for every event received - sounds like a bad plan.I could allocate the events dynamically and then send around pointers to those events, enqueue them in the array if wanted - but other than having reference counting - how would I be able to keep track of that memory? Do you know any way to implement a very light reference counter that wouldn't interfere with the user?
What do you think would be a good solution to this design?
Ok, first off, this line doesn't do what you think it does:
Event evt = EventKey(15, true);
This creates a temporary EventKey object, slices it to the base class Event, then calls the Event copy constructor. All actual data kept in the EventKey class is lost. If you want polymorphism, you want to use either dynamic objects or references.
As for your actual question, I'd recommend you redesign and have separate queues (and thus separate handlers) for each event type... onEventA, onEventB, etc.
Opinion: choose the reference counting option. Use boost::shareed_ptr, and boost::dynamic_pointer_cast to determine actual type.
You don't really need reference counting unless you share your event objects. If you only have one owner at any given time - in your case, it would normally be the event queue - then you simply need to use an appropriate container.
If your implementation has partially implemented C++0x already (e.g. recent g++ versions, or VC++2010), then you can simply use std::queue<std::unique_ptr<Event>>
. If std::unique_ptr
is not available, you can use boost::ptr_deque
or some other suitable container from the Boost Pointer Container library.
精彩评论