• Advertisement
Sign in to follow this  

how to make a function pointer point to different methods of different classes

This topic is 1240 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am trying to set up a messaging system in my game engine in c++. I already have a component based architecture set up, and I have different components for different game objects.

 

However, I only just started learining about function pointers, and have decided that my message system will call whatever function pointers are subscribed to certain message types in a list, or a map.

 

At first I wanted to just use a "recieve message" function in all my components and use a switch statement to decide what functions to call, but decided that function pointers would be a lot more flexible.

 

The problem is, I have different components of different types, that all inherit from an IGameComponent Interface. I tried using the std::function function variable, and tried to create a list of std::function<void(&IGameComponent)> types, but I got a compile time error when trying to access the functions.

 

Every component that inherits from IGameComponent has their own methods, which is the way I want it to be. It seems that std::function doesn't like calling member functions from inherited classes, and I cannot seem to get it to work. I cannot let the messaging system know about each and every game component type, otherwise I would get a circular dependency.

 

Here is an example of what I am trying to do:

#include <functional>
#include <iostream>

class IClass
{
public:
	IClass(){};
	virtual ~IClass(){};

	virtual void nopeFunction()=0;
};

class classWithMemberFunctions : public IClass
{
public:
	classWithMemberFunctions();
	virtual ~classWithMemberFunctions();

	void nopeFunction(){std::cout << "nope";};

	void memberFunction();

private:
int var1;
int var2;
float var3;
};

#include "classWithMemberFunctions.h"

classWithMemberFunctions::classWithMemberFunctions()
{

}

classWithMemberFunctions::~classWithMemberFunctions()
{

}


void classWithMemberFunctions::memberFunction()
{
	std::cout << "Function has been called.";
}


int main()
{
	classWithMemberFunctions class1;

	std::function<void(classWithMemberFunctions&)> functionPointer;

	std::function<void(IClass&)> functionPointer2;

	functionPointer = &classWithMemberFunctions::memberFunction;

	functionPointer2 = &classWithMemberFunctions::memberFunction;

	functionPointer(class1);    //This works!
	functionPointer2(class1);  //This doesn't work -.-

	std::cout << "Hello world!";
	return 0;
}

Any help would be greatly appreciated ^^.

Share this post


Link to post
Share on other sites
Advertisement

Never mind. It seems as though I have found the solution.

 

I decided to use std::bind to make the function global, and used a std::function<void()> pointer to allocate to the binded function.

 

Here is my code:

#include "classWithMemberFunctions.h"

#include <iostream>
#include <functional>
#include <map>

void output()
{

	std::cout << "output";

}

int main()
{
	classWithMemberFunctions class1;

	std::map<unsigned int, std::function<void()>> subscribersMap;

	std::function<void(classWithMemberFunctions&)> functionPointer;

	auto bindFunctionPointer = std::bind(&classWithMemberFunctions::memberFunction, &class1);

	std::function<void()>bindFuncPointer;

	bindFuncPointer = bindFunctionPointer;

	functionPointer = &classWithMemberFunctions::memberFunction;

	subscribersMap.insert(std::pair<unsigned int, std::function<void()>>(0, bindFuncPointer));

	subscribersMap.find(0)->second();

	functionPointer(class1);

	std::cout << "Hello world!";
	return 0;
}

Share this post


Link to post
Share on other sites

I had the same question recently and I went down the Boost route. They have a library for signals and slots, which looks kind of like this:
http://www.boost.org/doc/libs/1_56_0/doc/html/signals2.html
 

class Foo
{
public:
    void emitNope()
    {
        on_nope();
    }

    boost::signals2::signal<void()> on_nope;
};

class Bar
{
public:
    void onNope()
    {
         std::cout << "nope" << std::endl;
    }
};

int main()
{
    Foo foo;
    Bar bar;
    foo.on_nope.connect(boost::bind(&Bar::onNope, &bar));
    foo.emitNope();

    return 0;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement