Callback casting and set from another object - c++

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

Related

design pattern to avoid unnecessary addition of abstract functions to accommodate new functionality

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.

Call a function of an object referenced by a void Pointer

I have a function like this:
void something(void *obj)
{
obj->Set();
}
The compiler says that left of the dereference operator has to be a pointer to a class/struct/union/generic (translated from german not sure about wording).
The idea is that I want to call the something function of obj no matter what is passed to something. It is ensured that it has this function. How can i achieve that?
--EDIT--
I started to work on an existing Software which has like > 100 Classes for datatypes. In one part of the code there is a big switch statement which depending on an id creates an instance of one of these classes and calls the Set function for that one. Now i want to do multiple of these calls parallel, and because of this i want to bring the ->Set() call to a seperate function which i then can call in a new thread. Sadly there is no baseclass and i cant change too much in the "big picture". What is the best way to do this?
C++ doesn’t allow this (for good reasons: even if you can ensure that the object always has a function, C++ cannot, and since you can make mistakes, C++ is justified in distrusting you).
The proper way to do this is to have a common base class which defined this method for all types that you want to use here, and then use this common base class as the argument of this function.
Alternatively, if it’s known at compile time which type is used here, then the appropriate implementation uses templates:
template <typename T>
void f(T const& obj) {
obj.something();
}
Whatever you do, void* is not appropriate. There are very rare legitimate use-cases for it in C++.
You need a base class or interface for whatever is passed into doSth:
class Base
{
public:
virtual void something() = 0; //override this in derived classes
}
doSth(Base* obj)
{
obj->something();
}
You can also cast the void* back to the original type:
doSth(void* obj)
{
((Base*)obj)->something();
}
but passing a void* as parameter suggests a faulty design. What exactly are you trying to achieve?
You need to implement pure virtual Base class with this function:
class Base
{
public:
virtual ~Base(){}
virtual void somefunction()=0;
}
class Derived1: public Base
{
public:
void somefunction()
{
//do something
}
}
class Derived2: public Base
{
public:
void somefunction()
{
//do something
}
}
And than use dynmic cast to get Base* from void*
doSth(void *obj)
{
Base *bobj=dynamic_cast<Base*>(obj);
if ( bobj )
bobj->somefunction();
}
Or mor simplier:
doSth(Base *obj)
{
obj->somefunction();
}
And usage is like:
Base *p1 = new Derived1();
Base *p2 = new Derived2();
doSth(p1); // cals somefunction in Derived1 class
doSth(p2); // cals somefunction in Derived2 class
The doSth method could take a function pointer as a parameter.
doSth( (*someFunc)() ) {
obj->*someFunc();
}
The call would look like:
doSth( &function );
When passing function pointers between different classes you should create a typedef for each function pointer and use qualifiers for each function identifier.
Just define an interface that lists all the functions of all the objects that you want to reference by the pointer, but the type of this pointer should not be void, but the name of this interface instead.
Then you will be able to call every function of every object that you want by this pointer, but make sure that all structures and classes of the objects implement all the functions of the interface!
This is also important to write the : public and then the name of the interface in the header of every structure and class!

C++ member function pointers in class and subclass

I have one base class which holds a map for function pointers like this
typedef void (BaseClass::*event_t)();
class BaseClass {
protected:
std::map<std::string, event_t> events;
public:
// Example event
void onFoo() {
// can be added easily to the map
}
};
Handling this works prefect, but now i want to make BaseClass an abstract base class to derive from like this:
class SpecificClass : public BaseClass {
public:
void onBar() {
// this is gonna be difficult!
}
};
Although i can access the map from SpecificClass i am not able to add onBar because the event_t type is only defined for the BaseClass! Is there any possibility (maybe with templates?) which does not lead to define the event_t for each class i will use...
(It is not neccessary to use templates! Any good/suitable approach would be nice.)
More background information:
This whole thing is for a text based RPG. My base class could be called Location and the specifc one any location e.g. CivicCenter. Each Location object subscribes to my EventSystem which notifies all neccessary objects when i fire an event. Therefore i want to store in a map some pointers to private functions holding the actions with their "name" like onSetOnFire (xD) as the key.
This can't be done with your current map as it stands. Think about what would happen if you could put a child method into the map. Then you could pull a pointer-to-child-member (masquerading as base) out of the map, call it on a base class instance pointer, and then how would it call a derived class on a base class instance which obviously couldn't work.
Would a polymorphic approach work?
Yes; stop using member pointers.
The more correct way of doing what you want is to have an event type and an object pointer. So an event fires on a specific object. The event type would be a non-member function (or a static member). It would be passed the object pointer. And it would call some actual member function of that object.
Nowadays, the event type could be a std/boost::function. However, since the function parameters have to stay the same type for all events, this doesn't really fix your problem. You can't call SpecificClass::onBar from a BaseClass pointer unless you do a cast to a SpecificClass. And the event calling function would not know to do this. So you still can't put SpecificClass::onBar in the std/boost::function object; you still need some standalone function to do the cast for you.
This all just seems to be a terrible use of polymorphism. Why does SpecificClass need to derive from BaseClass at all? Can't they just be two unrelated classes?
You have to use static_cast:
event_t evt = static_cast<event_t>(&SpecificClass::onBar);
This is because it is slightly dangerous to cast to event_t, you could accidently apply it to a BaseClass instance.
How it works (for the skeptical):
class BaseClass {
public:
typedef void (BaseClass::*callback_t)(); // callback method
void doSomething(callback_t callback) {
// some code
this->*callback();
// more code
}
void baseCallback(); // an example callback
};
class DerivedClass : public BaseClass {
public:
void derivedCallback();
void doWhatever() {
// some code
doSomething(&BaseClass::baseCallback);
// more code
doSomething(static_cast<callback_t>(&DerivedClass::derivedCallback));
// et cetera
};
Here is what you should avoid, and why this is potentially dangerous:
void badCodeThatYouShouldNeverWrite()
{
BaseClass x;
// DO NOT DO THIS IT IS BAD
x.doSomething(static_cast<callback_t>(&DerivedClass::derivedCallback));
}
The requirement for a static_cast makes it so you can't "accidentally" pass DerivedClass method pointers in. And if you think this is dangerous, just remember that it's a pointer, and pointers are always dangerous. Of course, there are ways you can do this that involve creating helper classes, but that requires a lot of extra code (possibly making a class for every function you want to pass as a callback). Or you could use closures in C++11, or something from Boost, but I realize that a lot of us do not have that option.
After some thought and a redesign i was able to achieve what i wanted. Although i am stubborn and still using inheritance i have reimplemented the map. This is how it works now:
class Location {
// ...
protected:
std::map<std::string, std::function<void(void)>> m_mEvents;
};
And now i can handle it like this:
class CivicCenter : public Location {
public:
CivicCenter() {
// this is done by a macro which lookes better than this
this->m_mEvents["onTriggerSomething"] =
std::bind(&CivicCenter::onTriggerSomething, this);
}
void onTriggerSomething() {
// ...
}
// ...
};
With easy use of std::bind i am able to implement generic function pointers. When using parameters like in std::function<void(int, int)> remeber to use either boost's _1 and _2 or lambda expressions like me:
std::function<void(int,int)> f = [=](int a, int b) {
this->anotherFunctionWithParams(a, b);
};
But this is just pointed out due to completeness of my solution.

Downcasting a pointer using a function instead of giant if statement

I have a vector with pointers of type Vehicle. Vehicle is the base class and there are many derived types like MotorCycle, Car, Plane, etc. Now, in my program there comes a point where I need the derived type while traversing the vector. Each Vehicle class has a GetType() function which returns an int which tells me what the derived type is (motorcylce, car, plan). So, I can use a dynamic cast to downcast to the derived type from the base class pointer. However, I need to have a giant if statement everytime I need the derived pointer
if(vehicle_ptr->GetType() == PLANE)
Plane *ptr = dynamic_cast<Plane*> vehicle_ptr;
else if (vehicle_ptr->GetType() == MOTORCYCLE)
MotorCycle *ptr = dynamic_cast<MotorCycle*> vehicle_ptr;
..and on and on.
Is there a way to have a function or some trick I can call that would save me from the giant if statement everywhere? Like ::GetDerivedPtr(Vehicle *ptr). Would a template class help here? (never used them before) Sorry, my C++ is a bit rusty and I did search but these terms bring up too much material to find what I'm looking for. Thanks.
It looks like you've manually tried to recreate polymorphism. You don't need a type member. This is almost always a bad idea. Use polymorphism and virtual functions.
When you have a vehicle pointer v and do
v->function();
It will call the proper function for whatever type (Plane, Train, or Automobile) that the pointer actually points to if function is a virtual function. What you're doing is already handled by the language.
So:
class A {
public:
virtual void f() {cout << "A";}
};
class B : public A {
public:
virtual void f() {cout << "B";}
};
int main(){
A *a;
B b;
a = &b;
a->f();
}
The above snippet will print B.
I second the idea that you need some virtual function and a common base type. Imagine that there is some way to get the pointer which has the correct type. What will you do with it then? You'll have to make a giant switch anyway, because you call specific functions for each of your specific types.
One solution would be to invent a name for the operation you are trying to execute, and put its implementation as a virtual function at each specific Vehicle class. If the operation accepts different parameter for each of the cases, the parameters have to be packed into a special polymorphic structure/class, but here maybe the Visitor pattern is a more generic solution.
First check whether what you're going to do can be done simply via virtual functions in class Vehicle, overridden by each derived class.
If not, then consider the Visitor Pattern.
Cheers & hth.,
dynamic_cast will check the type itself (you don't need your own variable for this). You can do the following instead:
Plane *plane_ptr = dynamic_cast<Plane*>(vehicle_ptr);
if(plane_ptr != NULL)
{
// Do stuff with 'plane_ptr' that you couldn't do with 'vehicle_ptr'
}
I don't really see how creating a function to do the cast would help because you still need to class specific code anyway (and the function would have a fixed return type, so the closest you could get is something like the 'dynamic_cast' call, which is pretty much a standard function anyway).
Use Visitor based dispatching. Observe that not a simple cast of any kind is required in the follwing (somewhat trivialized) example:
// simple cyclic visitor
class VehicleVistor {
public:
// add overload for each concrete Vehicle type
virtual void Visit(class Motorcycle&) {};
virtual void Visit(class Plane&) {};
virtual void Visit(class Car&) {};
};
class Vehicle {
public:
virtual Accept(VehicleVisitor&) = 0;
};
class Car : public Vehicle {
public:
virtual Accept(VehicleVisitor& pVisitor) {
pVisitor.Visit(*this);
}
};
// and so on...
At some point of you program you need to retrieve all instances of, say Motorcycle:
class MotorcycleExtractingVisitor : public VehicleVisitor {
std::vector<Motorcycle*> mMotorcycles;
public:
void operator()(Vehicle* pVehicle) {
pVehicle->Accept(*this);
}
void Visit(Motorcycle& pMotorcycle) {
mAllMotorcycles.push_back(pMotorcycle);
}
std::vector<Motorcycles*> Get() { return mAllMotorcycles; }
};
class Extractor {
public:
// here you extract motorcycles
static std::vector<Motorcycle*> ExtractMotorcycles(std::vector<Vehicle*>& pVehicles) {
MotorcycleExtractingVisitor tMotos;
std::for_each(pVehicles.begin(), pVehicles.end(), tMotos);
return tMotos.Get();
}
// this would be a templatized version, left as exercise to the reader
template<class TExtracted, classtypename TBegItr, typename TEndItr>
static std::vector<TExtracted*> Extract(TBegItr pBeg, TEndItr pEnd) {
ExtractingVisitor<TExtracted> tRequiredVehicles;
std::for_each(pBeg, pEnd, tRequiredVehicles);
return tRequiredVehicles.Get();
}
};
Usage is as follows:
// fixed type version:
std::vector<Motorcycles*> tMotos =
Extractor::Extract(tVehicleVector);
// templatized version (recommended)
std::vector<Motorcycles*> tMotos =
Extractor::Extract<Motorcycles>(
tVehicleVector.begin(),tVehicleVector.end());

Polymorphism and checking if an object has a certain member method

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.