我正在尝试编写一个程序,该程序创建一个包含 vector 指向成员函数的指针的类,其中包含add()
和remove()
成员函数。
我写的代码是 -
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 }
但是,它在第32行显示错误 -
error C2440: 'type cast' : cannot convert from 'void (__thiscall FunctionVectors::* )(void)' to 'classFuncPtr'
请告诉我如何修改它才能正常工作。
提前致谢。
答案 0 :(得分:5)
typedef void(*classFuncPtr)();
这不是指向方法的指针,而是指向函数的指针。方法与函数不同,因为它在上下文中被调用:需要this
才能正常工作。
请记住,在C ++中,您只能创建指向特定类方法的指针向量。因此,您将无法在该向量中保留指向不同类的两种方法的指针。
解决方案 - 正如评论中所建议的那样 - 是使用std::function
或boost::function
以及可能是C ++ 11 lambdas,因为它们比简单的指向成员的指针提供了更多的灵活性。
如果要实现事件机制,请考虑使用仿函数而不是方法:
为事件处理程序创建基类:
class MyEventHandler
{
public:
virtual void operator()(void * sender, int data) = 0;
}
创建这些的简单向量:
std::vector<MyEventHandler *> MyEvent;
在班级中创建特定处理程序:
class MyClass
{
private:
class SpecificEventHandler : MyEventHandler
{
public:
void operator()(void * sender, int data)
{
std::cout << "Event handled!";
}
}
public:
SpecificEventHandler Handler;
MyClass()
{
}
}
将处理程序挂钩到您的活动:
MyEvent.push_back(&(myClassInstance.Handler));
从内存中编写的代码,可能无法编译,但你应该明白这一点。
答案 1 :(得分:1)
std::function< void() >
看起来像您正在寻找的签名。如果它在您的C ++版本中不可用,但您可以使用boost,那么您可以在boost中找到它。查找适用于std的适当标题的文档。
要为成员函数创建一个,您需要绑定它,并将其绑定到FunctionVectors::a()
,您需要一个FunctionVectors
的实例来调用它。
在您的示例中,我将为您创建typedef
typedef std :: function&lt; void()&gt; classFuncPtr; //实际上是一个命名错误的typedef
int main() { FunctionVectors f; classFuncPtr fv = std :: bind(&amp; FunctionVectors :: a,f); }
或者如果你真的有lambda的C ++ 11你可以做
classFuncPtr = [ f ]() { f.a() );
在你的情况下,我认为你并不真正想要一个免费的功能,你总是想要一个你想要的班级的成员功能。
typedef void (*FunctionVectors::classFuncPtr )();
你会用
(this->*func)();
调用它