I'm trying to write a program which creates a class that contains vector of pointers to member functions, with add()
and remove()
member functions.
The code I wrote is -
1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 typedef void(*classFuncPtr)();
6
7 class FunctionVectors
8 {
9 private:
10 vector<classFuncPtr> FunctionPointerVector;
11 public:
12 FunctionVectors(){}
13 void add(classFuncPtr funcPtr);
14 void remove(int index);
15 void run();
16 void a(){cout<<"a: Why are you calling me?"<<endl;}
17 };
18
19 void FunctionVectors::add(classFuncPtr funcPtr)
20 {
21 FunctionPointerVector.push_back(funcPtr);
22 }
23
24 void FunctionVectors::remove(int index)
25 {
26 FunctionPointerVector.erase(FunctionPointerVector.begin() + index);
27 }
28
29 int main()
30 {
31 FunctionVectors f;
32 classFuncPtr fv = &(classFuncPtr)FunctionVectors::a;
33
34 f.add(fv);
35 f.run();
36
37 return 0;
38 }
But, it is showing error in line# 32 -
error C2440: 'type cast' : cannot convert from 'void (__thiscall FunctionVectors::* )(void)' to 'classFuncPtr'
Please, tell me how should I modify it to work properly.
Thanks in advance.
typedef void(*classFuncPtr)();
This is not a pointer to method, but a pointer to function. Method differs from function, because it's being called in a context: requires this
to work correctly.
Keep in mind, that in C++ you are only able to create vector of pointers to a method of specific class. So you won't be able to keep pointers to two methods of different classes in that vector.
The solution - as suggested in comments - is to use std::function
or boost::function
and possibly C++11 lambdas, because they provide a lot more flexibility than simple pointer-to-members.
If you want to implement an event mechanism, consider also using functors instead of methods:
Create base class for event handler:
class MyEventHandler
{
public:
virtual void operator()(void * sender, int data) = 0;
}
Create simple vector of these:
std::vector<MyEventHandler *> MyEvent;
Create specific handlers in your classes:
class MyClass
{
private:
class SpecificEventHandler : MyEventHandler
{
public:
void operator()(void * sender, int data)
{
std::cout << "Event handled!";
}
}
public:
SpecificEventHandler Handler;
MyClass()
{
}
}
Hook the handler to your event:
MyEvent.push_back(&(myClassInstance.Handler));
Code written from memory, may not compile, but you should get the idea.
std::function< void() >
looks like the signature you are looking for. If it isn't available in your version of C++ but you can use boost, then you fill find it in boost. Look up documentation for appropriate header, for std, for function.
To create one for a member function, you need to bind it, and to bind it to FunctionVectors::a()
you will need an instance of a FunctionVectors
to call it on.
In your example, I will make the typedef for you
typedef std::function< void() > classFuncPtr; // in reality a badly named typedef
int main()
{
FunctionVectors f;
classFuncPtr fv = std::bind( &FunctionVectors::a, f );
}
alternatively if you really have C++11 with lambdas you can do
classFuncPtr = [ f ]() { f.a() );
In your case I reckon you don't really want a free function, you always want a member function of your class you want.
typedef void (*FunctionVectors::classFuncPtr )();
and you would use
(this->*func)();
to invoke it