Jump to content
  • Advertisement
Sign in to follow this  
Solid_Spy

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

This topic is 1423 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
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!