Hi,
I am relatively new to C++ and I am working on a personal project for practicing where I need to create a class that can take function pointers with different signatures.
The idea is that each instance of the class will store a pointer to a specific function and can call that function whenever I want.
To give a better idea of what I want, let me explain with a little bit more detail what I am trying to do. The project I am working on is a very basic console game and the object I am trying to create is an object that would store details on each location the player can access in the game.
(DISCLAIMER: I know that most of what I describe later is probably an overkill for a basic console game. I can easily make the whole game in a couple of files using just simple functions and I know how to do that. But the idea here is that I wanted to practice more advanced C++ techniques without having to figure out a complex project. So, since I know how to make a basic console game, I thought it would be a good idea to try and figure out how to achieve the same result but with more advanced techniques)
One of the details that I think should be stored is what happens in each location, basically the text that is output to the screen describing what happens and prompting the user to take action.
Since this would be different for each location, I can't just declare and implement a function in the class.
One way of solving this issue is to create a base class with a virtual function and then implement this function in a series of derived classes, each defining a new location.
The problem I have with this approach is that it makes each location a class that can be inherited further and instanced, which I don't need as I will only have 1 instance of each location.
I can of course just create 1 instance of the class, but I wanted to see if there is a way to avoid having to create separate classes for each location.
This why I started thinking of function pointers.
Now, I know I can declare a function pointer and initialise it in a class like that:
1 2 3 4 5 6 7 8 9
|
class Test
{
public:
Test(void (*p)())
: print{p}
{}
private:
void (*print)();
};
|
That works fine as long as the function returns void and accepts no arguments.
So, I thought maybe I can do that with a template:
1 2 3 4 5 6 7 8 9
|
template <typename Function>
class Test
{
public:
Test(Function *p)
: print{p}
{}
Function *print;
};
|
This actually works well. I can now have a class that accepts different functions with different return types.
I can create instances of the class in the following way:
1 2 3
|
void print();
Test<void ()> a {print};
|
However, I have one problem with this approach. Because it is a class template, I can't have a pointer that I want to use to point to instances of Test class regardless of the function that is passed to them.
For instance, if I declare the following pointer:
There is no way to re-assign that pointer to another instance of Test class unless the function pointer passed to it also returns void and accepts no arguments. Otherwise, I have to create a new pointer.
Is there a way to avoid that? Is there a better way of achieving what I am looking for than using function pointers?
Thank you very much and sorry for the long message.