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
Related
I just wanted to ask if my approach is wrong or one is the right way and it can be done.
In the project, I have one hal and several types of Dir based on Base.
When I create some dir I pass hal to it because each dir uses it in its own way.
Everyone also reacts in their own way to events in the hal. so I wanted to use the callback mechanism. I one moment I have only one specific controller, and I change it, delete, and create another, at this moment I must connect callback.
I create a solution with one dir type, and it's working fine.
But what path choose when I want to use a few different dir, Can I cast to base and use base in Hal something like this:
class Base;
class Hal
{
public:
void set_callback(void (Base::*callback)(int), Base* base)
{
m_callback = callback;
m_base = base;
}
void fun()
{
(m_base->*m_callback)(some_int);
}
private:
Base* m_base;
void (Base::*m_callback)(int);
};
#include "Hal.h"
class Base
{
public:
virtual void active() = 0;
virtual void foo(int variable) = 0;
};
class Dir : public Base
{
public:
Dir(Hal& hal)
: m_hal(hal)
{}
void active()
{
auto callback = &Dir::foo;
//add some casting?
m_hal.set_callback(callback, this);
}
void foo(int variable)
{
// some code
}
private:
Hal& m_hal;
};
Maybe I should add a separate class for routing such callbacks? Or use a different mechanism? Unfortunately, I don't have functional lib available in this project /:
Member function pointers for one class are not convertible to member function pointers of another class, even if the functions look compatible. You can approximate this conversion using a layer of abstraction, for example using a std::function<void(Base*, int)> but it cannot be achieved using a cast.
However, member function pointers respect polymorphism. The actual function being called will depend on the dynamic type of the object with which it is called.
You only need to pass &Bar::foo, which is virtual. Since it will be called with a Dir the Dir::foo override will be used.
Changing to m_hal.set_callback(&Bar::foo, this); should do what you want.
Live example : https://godbolt.org/z/fd8hsbanv
In below code I have abstract class TestAlgModule which I will be exposing to library users and there are several functionalities they can use such as VOLUME, MIXER and so on. However, suppose users need a new function which is added only in MixerManager then I need to add that in TestAlgModule abstract class and now suddenly all the derived class needs to add that without any benefit.
How do I avoid this?
#include <iostream>
using namespace std;
enum {VOLUME, MIXER, UNKNONWN};
class TestAlgModule {
public:
virtual void open(int type) = 0;
virtual void close(int type) = 0;
};
class volumeManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
};
class mixerManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
void differentFunction() {};
};
/* users calls this to get algModule and then call functions to get the job done */
TestAlgModule *getTestAlgModule(int type) {
switch(type) {
case VOLUME:
return new volumeManager();
case MIXER:
return new mixerManager();
default:
break;
}
return nullptr;
}
int main() {
TestAlgModule * test = getTestAlgModule(MIXER);
test->open();
//test->differentFunction(); this can't be called as it is not part of abstract class and users are exposed only abstract class
return 0;
}
If something is not clear please let me know and I will do my best to answer it. I am looking for a better way to do this i.e. change in VolumeManager should be independent of MixerManager.
If you want to use an abstract factory, like you did in above code, then you need to return a pointer to the base class. That is correct. And then you need to invoke all functions through the base pointer.
By the way, please do not use raw pointers. Please use std::unique pointers instead.
There are 2 possible solutions.
Add the interface functions as a none pure, but still virtual function to your base class, with a default behaviour.
virtual void differentFunction() {}
Because of the other pure functions, the base class is still abstract. This may lead to a fat interface. But in many cases it is an acceptable solution.
The second possibility is to downcast the base class pointer to your needed pointer, using dynamic_cast and checking the return value of the dynamic cast.
if(mixerManager* mm = dynamic_cast<mixerManager*>(test)) {
mm->differentFunction();
}
All this depends of course on the overall design and what you want to achieve. But the above 2 are the standard patterns.
There are also other design patterns that may fit your needs, like builder or prototype. Please check.
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.
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;
}
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.