I am trying to implement a typesafe event bus. I am stuck with the EventBus::subscribe function because it does not accept my concrete event handler. In an earlier version I had my AbstractEventHandler implemented as an abstract class only, without it being a template. I had no problem with that implementation. That's why I assume that the actual issue is with the abstract template.
The code below is a stripped down version of my implementation. The first block consist of the "skeleton" of the event bus and its required classes whereas the second block shows an actual implementation of the event, event handler and the main.
The enum holds all the different events available. The abstract event is the base of which all concrete events are derived of. The event handler is an abstract template with an event as template class to ensure type-safety. The event bus is responsible for distributing all published events to its respective handlers.
enum EVENT_TYPE
{
ON_EVENT_1,
ON_EVENT_2
};
class AbstractEvent
{
public:
AbstractEvent() {};
virtual ~AbstractEvent() {};
virtual EVENT_TYPE type() = 0;
};
template<class T>
class AbstractEventHandler
{
public:
AbstractEventHandler() {};
virtual ~AbstractEventHandler() {};
virtual void on_event(T *event) = 0;
};
class EventBus
{
public:
EventBus() {};
virtual ~EventBus() {};
void subscribe(EVENT_TYPE type,
AbstractEventHandler<AbstractEvent> *eventHandler) {
// Add handler to vector for further use
}
void publish(AbstractEvent *event) {
// send event to each handler in respective vector
}
};
Below are my concrete event and event handler and the main()
class ConcreteEvent : public AbstractEvent
{
public:
ConcreteEvent() {};
virtual ~ConcreteEvent() {};
EVENT_TYPE type() {
return ON_EVENT_1;
};
};
class ConcreteEventHandler : public AbstractEventHandler<ConcreteEvent>
{
public:
ConcreteEventHandler() {}
virtual ~ConcreteEventHandler() {};
void on_event(ConcreteEvent *event) {
// Do something
};
};
int main()
{
EventBus *eventBus = new EventBus();
ConcreteEventHandler handler = ConcreteEventHandler();
// This failes!
eventBus->subscribe(ON_EVENT_1, &handler);
}
The compiler returns with an error saying that there is no matching function for call to
EventBus::subscribe(EVENT_TYPE, ConcreteEventHandler*)
and that the only candidates are
void EventBus::subscribe(EVENT_TYPE, AbstractEventHandler<AbstractEvent>*)
How can I implement my EventBus::subscribe method to accept concrete implementations of my abstract class?
Update: Solution
I have changed the method description of EventBus::subscribe to the following and it now works nicely:
template<typename T>
void subscribe(EVENT_TYPE type, AbstractEventHandler<T> *eventHandler) {
}
Thanks, Rohan, for your hints! They helped me to find this solution.
The reason is because, ConcreteEventHandler is a subclass of AbstractEventHandler<ConcreteEvent> and not AbstractEventHandler<AbstractEvent>.
This might seem surprising, but AbstractEventHandler<ConcreteEvent> cannot be a subclass of AbstractEventHandler<AbstractEvent> even though ConcreteEvent is a subclass of AbstractEvent.
The reason is because, with templates, templating as you wish does not guarantee type safety. Let us look at an example. Let's go over the standard paradigm of a base-class Animal and sub-classes Cat and Dog. Let's say we have a list of Animals:
std::list<Animals>* animals;
and a list of cats:
std::list<Cat> cats;
The following, is NOT a valid cast:
animals = &cats;
The reason is, because, if I am to do this,
animals->add(new Dog("Ben"));
I would actually add a Dog to a list of Cats. cats.last() here would actually return a Dog. So, in this case, you are essentially adding a Dog to a list of Cats. I've seen enough Looney Tunes episodes to know that this is not a good idea:
cats.last().meow();
The above is definitely not true, as we all know that a Dog can only bowbow().
EDIT
To answer your question, here is what I suggest you do; Let ConcreteEventHandler inherit from AbstractEventHandler<AbstractEvent>, and within the code, wherever you use a ConcreteEvent, use a dynamic_case to cast the AbstractEvent to a ConcreteEvent. This will use run-time introspection, which might impact performance a little (also I have seen quite a few people opposed to using a dynamic cast), but you will be able to successfully perform a valid upcast of the datatype.
Rohan already answered why the code doesn't compile, however I would like to suggest another approach.
You could implement it in a way that the Eventhandler subscribes directly to the EventGenerator. This way there is a direct link between generating and handling the event.
The event should then hold a reference to its generator to let it access the subscribed handlers and the eventbus calls a method on the event to let it handle itself.
This way, the eventbus is unaware of eventhandlers and you don't even need an eventtype enum.
However, you need different eventgenerators that need to be accessible by different eventhandlers as opposed to one eventbus. Every eventhandler can handle only one event, so if more events are needed, eventhandlers should be aggregated (by delegation or inheritence).
Your AbstractEventHandler<T> class should inherit AbstractEvent. This was probably your intent, you just forgot to write it.
template<class T>
class AbstractEventHandler
:public AbstractEvent
{
public:
AbstractEventHandler() {};
virtual ~AbstractEventHandler() {};
virtual void on_event(T *event) = 0;
}
Related
I am writing a C++ library and I would like to hide the name of a base class, i.e. I do not want the user to be able to use a base class pointer (or reference) to refer to the derived classes.
Let's say I have a class
class Message
{
public:
//...
};
and two derived classes:
class SpecialMessage : public Message
{
//..
};
class NeatMessage : public Message
{
//..
};
How to make it so the user can't do something like:
SpecialMessage specialMessage{};
Message* baseHandle = &specialMessage;
One reason I want to preclude this behavior is I do not want to declare the Message's destructor to be virtual.
I thought about hiding the Message in a detail namespace:
namespace detail
{
class Message
{
};
}
but this is kinda weird and the user could still get to the Message class if the are so inclined.
EDIT:
Private inheritance will not work for me as I still want the user to be able to access the Message's methods (thru the derived class's object). Neither will composition -- because in order to make the Message's methods accessible to the user I would have to write wrapper code in the derived classes.
Declaring the base class's destructor as protected (as suggested by Sebastian Redl), although an interesting idea, also will not work for me as it still allows the user to get a base class handle.
You could inherit privately, or you could embed a Message object inside SpecialMessage instead of deriving.
Or if you never actually need raw Message objects, you could make Messages destructor protected.
Use protected or private inheritance instead of public:
class SpecialMessage : private Message {};
Or, to solve your real problem of not having a virtual destructor, just make Message's destructor protected. Then even though they can make a base class pointer, they can't non-polymorphically destroy the object through it.
I have to ask you to consider your design though: Why do you want a Message interface at all? If the base class is completely non-polymorphic you should absolutely use composition or private inheritance instead of public inheritance. Public inheritance is to be used only for substitution, not implementation.
Favor composition over inheritance. If you inherit from Message, there is no way I can think of to hide its declaration from the user. Of course you could obscure it, like you suggested, but the declaration has to be there - period.
If you use Message as a private member and don't ship the source code of your library, the user will not see the declaration. For your users to be able to access functions of Message, use the facade pattern.
There's probably a better way to provide the semantics you require with a different architecture. However, to work around this issue you can always do some gross template magic like this:
#include <iostream>
class Message
{
public:
void Foo() {}
int Bar(int i) {return i + 10;}
};
class SpecialMessage
{
private:
Message message;
public:
template<typename T, typename... Args>
auto MessageCall(T t, Args... args) -> decltype((message.*t)(args...))
{
return (message.*t)(args...);
}
};
int main()
{
SpecialMessage m;
m.MessageCall(&Message::Foo);
std::cout << "\n test: " << m.MessageCall(&Message::Bar, 10);
return 0;
}
A little bit dirty, yeah...
I do this a lot:
class Child{
Control*parent;
public:
Child(Control*theParent):parent(theParent){}
};
class Control{
Child child;
void makeChild(){ child=Child(this); }
//Control() : child(this) { } //another example
}
So the Control owns and operates the child, but the child still has reference to the parent Control.
When I read general topics on program design patterns, etc, it seems like this method of organizing objects is not particularly recommended. I realize there are risks, for example you don't want your child to abuse its parent by making its parent do things that only the parent should decide to do on its own; in which case, seems easy to prevent by making sure the parent's critical methods are private. But then you might have another controller that manages the parent, in which case some methods should be public, and now your child has access to those too, when really only some other controller should manipulate those.
So I can see how this can be dangerous.
But my question is, what is a common alternative? You need a parent to own a child, but you need the child to be able to notify the parent of things occasionally. How, if not the above?
Objective-C has the NSNotificationCenter which allows notifications without actually passing references, but this also makes it easy to create organizational problems (why is my child sending out this notification, and who is going to receive it?)
You can separate them by an interface:
class IListener {
public:
virtual void notify (int somevalue) = 0;
~IListener() {};
}
class Child{
private:
IListener *listener;
public:
Child(IListener *theListener):listener(theListener){}
};
class Control: public IListener {
private:
Child child;
public:
makeChild(){ child(this) };
virtual void notify(int someValue) { doSomething(someValue);};
}
(This is a simple version of the observer pattern, BTW).
It sounds like you are looking for the observer pattern.
In the observer pattern, an object maintains a list of dependents (aka observers) and notifies them of changes as required. In your case, the Control class is the observer and the Child class is the notifier.
The Boost library has a signal/slot mechanism that can be used to implement this:
http://www.boost.org/doc/libs/1_49_0/doc/html/signals/tutorial.html#id3137144
There's an example of using this on SO:
Complete example using Boost::Signals for C++ Eventing
Throwing another idea in the ring, it would seem that a Friend class can go a long way with this as well.
Methods that a child should not have access to are made private or protected. That way the child cannot do any damage you don't want it to do.
Then if you need another class to manage your parent controller, your parent class makes that other class a friend so it can access all those private methods you withhold from the child.
When I read general topics on program design patterns, etc, it seems like this method of organizing objects is not particularly recommended.
This is so wrong, because of inversion of control. You could have created it as Child's member variable. Martin Fowler has a very nice article explaining one kind of inversion of control (dependency injection).
Here is an example explaining briefly how to implement dependency injection (dependency injected through constructor) :
#include <iostream>
struct B
{
virtual ~B(){}
virtual void foo() = 0;
};
struct A1 : public B
{
virtual ~A1(){}
virtual void foo()
{
std::cout<<"hello"<<std::endl;
}
};
struct A2 : public B
{
virtual ~A2(){}
virtual void foo()
{
std::cout<<"test"<<std::endl;
}
};
struct C
{
C( B &b_ ) : b(b_){}
void bar()
{
b.foo();
}
B &b;
};
#define SAY_HI
int main()
{
#ifdef SAY_HI
A1 a;
#else
A2 a;
#endif
C c(a);
c.bar();
}
If you think about design patterns, you'll notice some of them use some kind of inversion of control. Here are some well-known (from this link) :
observer
decorator
By the way, what you have is called chain of responsibility.
It's a bit hard to explain in words, so I'll give an example:
(The following code might have incorrect syntax but it suffices to give an idea)
class A
{
public:
static void Update(UINT someValue);
};
class B : public A
{
public:
static void Update(UINT someValue);
};
class C : public A
{
public:
static void Update(UINT someValue);
};
I know static members function do not override each other,
but let's suppose they do.
What I want to achieve, is when A::Update(someValue); is called,
It should implicitly call B::Update(someValue), and also C::Update(someValue), as well as call every static void Update(UINT someValue) method of other classes derived from A
Is this possible in one way or another?
And if it is, how would you do it?
I think you should be using composite pattern instead. You can read about it at http://en.wikipedia.org/wiki/Composite_pattern and http://www.javacamp.org/designPattern/composite.html
That info below my comment is not enough to have a clear idea about your code but I was thinking if it is possible to do something similar to what C# does with events, where you can register events and the class that triggers then (your base class in that case) can implement a list of function pointers (pointing to the derived methods, which in that case you have to have instances of the derived classes) and call all of then iterating this list. Just an idea, don't know if this is what you need.
There's no way to do it automatically. A simple way to get the effect is for each derived class to call the function of its base class:
class A
{
public:
static void Update(UINT someValue) {
std::cout << "A\n";
}
};
class B : public A
{
public:
static void Update(UINT someValue) {
A::Update(someValue);
std::cout << "B\n";
}
};
If you prefer to work from bottom to top, you could have each class do its work before calling the derived class. Of course there's nothing to stop a derived class from implementing Update and not calling its base class. It is however fine for a class to not implement Update at all -- it doesn't care about updates, but its base class's function can still be called. So it's not a huge burden on implementers, they just have to follow the rule that if they implement the function, they have to call the base.
Another way might be for the base class to keep a list of "listeners" who are interested in updates, and to call them in turn whenever an update occurs. Each derived class can then register a suitable listener.
It might be difficult to make code like this exception-safe, though, if each level makes changes but one or more levels may throw.
I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.
the following class hierarchies represent abstract resource handler and resource hierarchies. Both have the interfaces as base classes. Now imagine you write a system where you can implement multiple specific resource systems under these interfaces. Here is just one example. The specific main class creates the resources derived from stuff. Now when the created resource is handed to the base interface it is handed as a pointer to the base resource class but i want to handle the specific resource and have access to its specific attributes.
I know about double dispatch, but i don't think it works in this case. I would like to prevent RTTI and dynamic_casts. Do you have suggestions as to handle such cases?
class resource;
class main_resource_handler
{
public:
virtual resource* create_resource() = 0;
virtual void do_some(resource* st) = 0;
};
class resource
{
};
class specific_resource : public resource
{
public:
int i;
};
class specific_resource_handler : public main_resource_handler
{
public:
stuff* create_resource) {
return new specific_resource);
}
void do_some(resource* st) {
// in here i want to work with specific resource
}
void do_some(specific_resource* st) {
// i want to get here
}
}
main_resource_handler* handler = new specific_resource_handler();
resource* res = handler->create_resource();
handler->do_some(res); /// here
I think you're not asking the right question.
To do what you're asking, all you need is to add this:
template<typename T>
class helper : public main_resource_handler
{
public:
virtual resource* create_resource() { return new T; }
virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); }
private:
virtual void do_some_specific(T* st) = 0;
};
And change this:
class specific_resource_handler : public helper<specific_resource>
{
private:
virtual void do_some_specific(T* st) { ... }
}
The static_cast is only safe if you can guarantee that you will always call do_some on the right type of handler. But if you already know it's the right kind of handler, then there's no need to make a base-class method call. So presumably what you want is to get some sort of resource, not knowing its exact type, and pass it to the appropriate handler. That's trickier...
I wonder if the Curiously recurring template pattern is what you are looking for. There is already a thread on stackoverflow on this topic.
I'm not sure why you need both the resource and the handler - it seems you're exposing an extra coupling to something with would be encapsulated. The problem wouldn't exist if create resource just returned a resource that the client could call methods on directly.
If you want safety, have the resource remember the address of the handler which created it, then check that in do_some(resource* st). If the resource was created by the current handler, and a handler can only create resources of a given kind, then it's safe to cast it and call the specific function. Though as above, if the function was just a virtual function on the resource it would be by definition type safe.
I think you may be looking for this:
http://www.artima.com/cppsource/cooperative_visitor.html