Function pointer to a non-static member function when the class type is unknown? - c++

I'm working on a game project that features scratch-built controls rendered into an opengl context; things like buttons, scrollbars, listboxes, etc. Many of these controls are nested; for example, my listbox has a scrollbar, a scrollbar has 3 buttons, etc.
When a scrollbar changes value, I'd like it to call 'some' function (typically in it's parent object) that responds to the change. For example, if the listbox has a slider, it should instantiate the slider, then tell the new slider that it should call the listboxes 'onScroll(float)' function. All of the controls share a common base class, so I could have a 'base* parent' parent pointer, then do 'parent->onScroll(val)'. The problem though is what happens when the parent doesn't inheirit from base; there'd be no virtual onScroll() to follow through, so the top-level parent would have to periodically check to see if any of the child controls had changed value. This would also clutter up other controls, since they may not even have children, or may require different event types like when a list entry object is selected, etc.
A better solution would be to have the child object maintain a generic function pointer (like a callback), which can be set by the parent, and called by the child as necessary. Something like this:
typedef (*ptFuncF)(float);
class glBase {
public:
//position,isVisible,virtual mouseDown(x,y),etc
};
class glDerivedChild : public glBase {
public:
glDerivedChild();
~glDerivedChild();
void changeValue(float fIn) {
Value = fIn; //ignore these forward declaration errors
(*callBack)(fIn);
}
void setCallBack(ptFuncF pIn) {callBack = pIn;}
ptFuncF callBack;
float Value;
};
class glDerivedParent : public glBase {
public:
glDerivedParent() {
child = new glDerivedChild();
child->setCallBack(&onScroll);
}
~glDerivedParent() {delete child;}
void onScroll(float fIn) {
//do something
}
glDerivedChild* child;
};
class someFoo {
public:
someFoo() {
child->setCallBack(&setValue);
}
void setValue(float fIn) {
//do something else
}
glDerivedChild child;
};
I'm kinda new to function pointers, so I know I'm (obviously) doing many things wrong. I suspect it might involve something like "typedef (glBase::*ptFuncF)(float);" with the 'onScroll(f)' being an overridden virtual function, perhaps with a generic name like 'virtual void childCallBack(float)'. I'd prefer to keep the solution as close to vanilla as possible, so I want to avoid external libraries like boost. I've been scratching my head over this one for the better part of 8 hours, and I'm hoping someone can help. Thanks!

I think, what you want is some kind of events or signals mechanism.
You can study, how event processing is organized on Windows, for example. In short, your scrollbar generates new event in the system and then system propagates it to all elements, registered in the system.
More convenient mechanism is signal/slot mechanism. Boost or Qt provides such tools. I'll recomend this solution.
But if you still want to use just callbacks, I'll recommend using std::function (boost::function) (combined with std::bind (boost::bind), when required) instead of raw function pointers.

Use boost::function (or std::function if available). Like this (using your notation):
typedef std::function<void (float)> ptFuncF;
//...
void setCallBack(const ptFuncF &pIn);
//...
child->setCallBack(std::bind(&glDerivedParent::onScroll, this, _1));
//...
child->setCallBack(std::bind(&someFoo::setValue, this, _1));

A function pointer to a member function of a class has such a type:
<return type> (<class name>::*)(<arguments>)
For example:
typedef void (glBase::*ptFuncF)(float);
^^^^
by the way, you have forgot the `void` in your `typedef`
ptFuncF func = &glDerivedChild::onScroll;
And you use it like this:
glDerivedChild c;
(c.*func)(1.2);
In your particular example, the function is a member of the derived class itself, therefore you should call it like this:
(c.*c.callback)(1.2);
the inner c.callback is the function pointer. The rest is exactly as above, which is:
(class_instance.*function_pointer)(arguments);
You might want to take a look at this question also.

Ok, the workaround I came up with has some extra overhead and branching, but is otherwise reasonable.
Basically, each callback function is implemented as a virtual member function that recieves the needed parameters including a void* pointer to the object that made the call. Each derived object also has a base-class pointer that refers to the object that should recieve any events that it emits (typically its parent, but could be any object that inheirits from the base class). In case the control has multiple children, the callback function uses the void* pointer to distinguish between them. Here's an example:
class glBase {
public:
virtual onChildCallback(float fIn, void* caller);
glBase* parent;
};
class glSlider : public glBase {
public:
glSlider(glBase* parentIn);
void changeValue(float fIn) {
Value = fIn;
parent->onChildCallback(fIn, this);
}
float Value;
};
class glButton : public glBase {
public:
glButton(glBase* parentIn);
void onClick() {
parent->onChildCallback(0, this);
}
};
class glParent : public glBase {
public:
glParent(glBase* parentIn) : parent(parentIn) {
childA = new glSlider(this);
childB = new glButton(this);
}
void onChildCallback(float fIn, void* caller) {
if (caller == childA) {
//slider specific actions
} else if (caller == childB) {
//button specific actions
} else {
//generic actions
}
}
glSlider* childA;
glButton* childB;
};
Besides a reasonably small amount of overhead, the scheme is flexible enough that derived classes can ignore certain components or omit them altogether. I may go back to the function pointer idea later (thanks shahbaz), but half the infrastructure is the same for both schemes anyway and the extra overhead is minimal, especially since the number and variety of controls will be rather small. Having the callback function use a nested response is actually a little better since you don't need a separate function for each child object (eg onUpButton, onDownButton, etc).

Related

Function pointer, Functor or Lambda?

I'm relatively new to C++, having spent years with Obj-C, and wondering about how to add what would be closure block in Obj-C, to a C++ class. Here's some pseudo code of what I want to do:
class Slider
{
public:
void onMouseDown()
{
if(rightClick or ctlKeyDown)
{
if(myFunctionPointer != nil)
{
// show popup menu
myFunctionPointer(this);
}
}
}
FunctionPointer myFunctionPointer = nil;
};
class Editor
{
public:
void showPopupMenu(Slider *s)
{
// build the popupMenu with information based on the slider
}
void init()
{
// create a slider and connect the popupMenu function to it
mySlider = new Slider;
mySlider->functionPointer = showPopupMenu();
}
Slider *mySlider;
};
As you can see, I'm trying to get my Slider class to call a function without knowing anything about it.
This shouldn't be that difficult, but I'm interested in doing it the best/proper way. Lambdas and functors look incredibly confusing. Maybe I'm looking for something else. But what?
When it comes to treating function as objects, your basic options are: function pointer, functor/lambda, std::function. I am going to assume that you can find out their syntax and will focus on their difference.
A function pointer should be used when there is no need for a closure. This applies when the procedure you want to call is stateless or has a global state, and you have all parameters in the scope.
A functor should be used when you need to create a closure. Since functors are objects, you can maintain an internal state and pass parameters inside the closure.
A lambda is essentially a functor, without an explicit typename. The capture list of a lambda is its member if it were implemented as a functor instead. Note that you can overload operator() for a functor but not a lambda.
The problem with functor/lambdas is that each of their definition has a different type, and can be ill-suited in function signature/class member types. std::function resolves the problem by being able to accept functor/lambda/function pointer and convert them to a uniform type of std::function. You pay a (often small) price for this flexibility in the form of performance though.
Lambdas and functors are one of the most advanced C++ topics. You're better off starting with some fundamentals before, and have a solid understanding of how C++ classes work.
But, since you asked, the C++ equivalent of this should be something like this:
class Slider
{
public:
void onMouseDown()
{
if(rightClick or ctlKeyDown)
{
if(myFunctionPointer)
{
// show popup menu
myFunctionPointer(this);
}
}
}
std::function<void (Slider *)> myFunctionPointer=nullptr;
};
class Editor
{
public:
void showPopupMenu(Slider *s)
{
// build the popupMenu with information based on the slider
}
void init()
{
// create a slider and connect the popupMenu function to it
mySlider = new Slider;
mySlider->functionPointer = [this](Slider *)
{
showPopupMenu();
};
}
Slider *mySlider;
};
As I said, I think that you're better off focusing your efforts on getting the fundamentals down pat, first, before plunging into these shark-infested waters.
And just to add some additional color: this will compile (the only thing that's missing is the definitions of rightClick or ctlKeyDown), but it may or may not be right, depending on the scope and the lifetime of the objects involved. It may or may not be necessary to have the lambda capture a std::shared_ptr, instead of this, depending on how the objects in this application get instantiated. Understanding how C++ objects work would be a necessary prerequisite before dealing with closures and callbacks, of this sort.
There are different ways to achieve what you're looking for.
Here's a way, avoiding function pointers.
I didn't correct some other obvious mistakes, like the memory leak that arises from callingnew and never deleting the object.
Best practice in this case would be using a std::unique_ptr
class Slider
{
public:
Slider(Editor& e)
: _e(e)
{ }
void onMouseDown()
{
if(rightClick or ctlKeyDown)
{
_e.showPopupMenu(this);
}
}
Editor& _e;
};
class Editor
{
public:
void showPopupMenu(Slider *s)
{
// build the popupMenu with information based on the slider
}
void init()
{
// create a slider and connect the popupMenu function to it
mySlider = new Slider(*this);
}
Slider* mySlider;
};
Here's another solution moving a functor directly in the constructor, however using templates.
template <typename Handler>
class Slider
{
public:
Slider(Handler&& h)
: _h(std::move(h))
{ }
void onMouseDown()
{
if(rightClick or ctlKeyDown)
{
// show popup menu
_h(this);
}
}
Handler _h;
};
class Editor
{
public:
void showPopupMenu(Slider *s)
{
// build the popupMenu with information based on the slider
}
void init()
{
// create a slider and connect the popupMenu function to it
mySlider = new Slider([this](Slider* s){ showPopupMenu(s); });
}
Slider *mySlider;
};
You could also use a std::function instead, as shows on another answer

Are templates the best option? If so, is this the correct syntax?

So I have this:
//base class
class InterfaceItem
{
public:
//iterates through m_SubItems vector looking for an item with that name and
//returns it
InterfaceItem* GetSubItem(string Name);
private:
vector<InterfaceItem*> m_SubItems;
}
//one of the classes that derive from InterfaceItem
class Window : public InterfaceItem
{
//other functions
}
So if I do something like
Window ThisWindow; //pretend it is already initialized and has sub-items
ThisWindow.GetSubItems();
it will return an object of type InterfaceItem*, so I am not able to access any of the Window specific functions unless I do something like
Window* TempWindow = static_cast<Window*>(ThisWindow.GetSubItems());
What is the best solution for this? Is it to use a function template? If so, would this be the correct syntax?
class InterfaceItem
{
public:
template<class Type*> Type* GetSubItem(string Name);
private:
vector<InterfaceItem*> m_SubItems;
}
I've tried this and I got some WEIRD errors. Files that pretty had nothing to do with this started saying classes that were clearly #included didn't exist and some other weird stuff
Using the static_cast on the calling side is actually a good way to go. You will need to call that static_cast somewhere. If you don't call it on the receiving side, you will need to call it inside the GetSubItem.
Even better way, if you have RTTI enabled and are OK with sacrificing a little bit of performance, is to use dynamic_cast instead. The difference is that dynamic_cast would only succeed if the value the subItem points to is in fact an instance of type Window, otherwise it will return nullptr. This way you can write:
Window* TempWindow = dynamic_cast<Window*>(ThisWindow.GetSubItems());
if (nullptr != TempWindow) {
// process the window
}
else { // that particular subitem is not a Window*
// handle failure somehow
}

Type-casting to an abstract class?

I'm writing an event-based messaging system to be used between the various singleton managers in my game project. Every manager type (InputManager, AudioManager, etc) is derived from a base Manager class and also inherits from an EventHandler class to facilitate message processing, as follows:
class Manager
{ ... }
class EventHandler
{ ...
virtual void onEvent(Event& e) =0;
...
}
class InputManager : public Manager, public EventHandler
{ ...
virtual void InputManager::onEvent(Event& e);
{ ... }
}
Elsewhere I have an EventManager that keeps track of all EventHandlers and is used for broadcasting events to multiple recievers.
class EventManager
{...
addHandlerToGroup(EventHandler& eh);
{ ... }
...
}
Naturally when I'm initializing all of my singleton Managers, I want to be adding them as they're created to the EventManager's list. My problem is that MVC++ complains at compile-time (and as I'm coding with squiggly lines) whenever I attempt to cast my Managers to EventHandlers. I thought it would work as follows:
int main()
{ ...
EventManager* eventM = new EventManager();
...
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
}
The compiler, however, informs me that "a cast to abstract class is not allowed." I was under the impression that you can...after all, polymorphism doesn't do you much good without passing objects back and forth with a bit of flexibility as to how close to the base class they are interpreted. My current workaround looks like this:
int main()
{ ...
EventManager* eventM = new EventManager();
EventHandler* temp;
...
InputManager* inputM = new InputManager();
temp = inputM;
eventM->addHandlerToGroup(*inputM);
}
Which, as far as I can tell, is the same conceptually for what I'm trying to accomplish, if a bit more verbose and less intuitive. Am I completely off as far as how typecasting with polymorphism works? Where am I going wrong?
in EventManager, declare the method addHandlerToGroup as
void addHandlerToGroup(EventHandler* handler);
then, just remove the cast. pass the pointer (in the example inputM) as it is to the addHandler method, and you should be fine :)
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
I think you just lost track of what you were doing. In this code, inputM is an InputManager* and you are trying to cast it to an EventHandler. That is, you are trying to cast a pointer to one class to an instance of another class. That, of course, makes no sense.
You can cast a pointer to an instance of a derived class to a pointer to an instance of one of its base classes. I think that's what you meant to do.

handling pointer to member functions within hierachy in C++

I'm trying to code the following situation:
I have a base class providing a framework for handling events. I'm trying to use an array of pointer-to-member-functions for that. It goes as following:
class EH { // EventHandler
virtual void something(); // just to make sure we get RTTI
public:
typedef void (EH::*func_t)();
protected:
func_t funcs_d[10];
protected:
void register_handler(int event_num, func_t f) {
funcs_d[event_num] = f;
}
public:
void handle_event(int event_num) {
(this->*(funcs_d[event_num]))();
}
};
Then the users are supposed to derive other classes from this one and provide handlers:
class DEH : public EH {
public:
typedef void (DEH::*func_t)();
void handle_event_5();
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
........
}
};
This code wouldn't compile, since DEH::func_t cannot be converted to EH::func_t. It makes perfect sense to me. In my case the conversion is safe since the object under this is really DEH. So I'd like to have something like that:
void EH::DEH_handle_event_5_wrapper() {
DEH *p = dynamic_cast<DEH *>(this);
assert(p != NULL);
p->handle_event_5();
}
and then instead of
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
in DEH::DEH()
put
register_handler(5, &EH::DEH_handle_event_5_wrapper);
So, finally the question (took me long enough...):
Is there a way to create those wrappers (like EH::DEH_handle_event_5_wrapper) automatically?
Or to do something similar?
What other solutions to this situation are out there?
Thanks.
Instead of creating a wrapper for each handler in all derived classes (not even remotely a viable approach, of course), you can simply use static_cast to convert DEH::func_t to EH::func_t. Member pointers are contravariant: they convert naturally down the hierarchy and they can be manually converted up the hierarchy using static_cast (opposite of ordinary object pointers, which are covariant).
The situation you are dealing with is exactly the reason the static_cast functionality was extended to allow member pointer upcasts. Moreover, the non-trivial internal structure of a member function pointer is also implemented that way specifically to handle such situations properly.
So, you can simply do
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, static_cast<EH::func_t>(f5));
........
}
I would say that in this case there's no point in defining a typedef name DEH::func_t - it is pretty useless. If you remove the definition of DEH::func_t the typical registration code will look as follows
DEH() {
func_t f5 = static_cast<func_t>(&DEH::handle_event_5);
// ... where `func_t` is the inherited `EH::func_t`
register_handler(5, f5);
........
}
To make it look more elegant you can provide a wrapper for register_handler in DEH or use some other means (a macro? a template?) to hide the cast.
This method does not provide you with any means to verify the validity of the handler pointer at the moment of the call (as you could do with dynamic_cast in the wrapper-based version). I don't know though how much you care to have this check in place. I would say that in this context it is actually unnecessary and excessive.
Why not just use virtual functions? Something like
class EH {
public:
void handle_event(int event_num) {
// Do any pre-processing...
// Invoke subclass hook
subclass_handle_event( event_num );
// Do any post-processing...
}
private:
virtual void subclass_handle_event( int event_num ) {}
};
class DEH : public EH {
public:
DEH() { }
private:
virtual void subclass_handle_event( int event_num ) {
if ( event_num == 5 ) {
// ...
}
}
};
You really shouldn't be doing it this way. Check out boost::bind
http://www.boost.org/doc/libs/1_43_0/libs/bind/bind.html
Elaboration:
First, I urge you to reconsider your design. Most event handler systems I've seen involve an external registrar object that maintains mappings of events to handler objects. You have the registration embedded in the EventHandler class and are doing the mapping based on function pointers, which is much less desirable. You're running into problems because you're making an end run around the built-in virtual function behavior.
The point of boost::bindand the like is to create objects out of function pointers, allowing you to leverage object oriented language features. So an implementation based on boost::bind with your design as a starting point would look something like this:
struct EventCallback
{
virtual ~EventCallback() { }
virtual void handleEvent() = 0;
};
template <class FuncObj>
struct EventCallbackFuncObj : public IEventCallback
{
EventCallbackT(FuncObj funcObj) :
m_funcObj(funcObj) { }
virtual ~EventCallbackT() { }
virtual void handleEvent()
{
m_funcObj();
}
private:
FuncObj m_funcObj;
};
Then your register_handler function looks something like this:
void register_handler(int event_num, EventCallback* pCallback)
{
m_callbacks[event_num] = pCallback;
}
And your register call would like like:
register_handler(event,
new EventCallbackFuncObj(boost::bind(&DEH::DEH_handle_event_5_wrapper, this)));
Now you can create a callback object from an (object, member function) of any type and save that as the event handler for a given event without writing customized function wrapper objects.

calling a function from a set of overloads depending on the dynamic type of an object

I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.