映射不同类的成员函数指针
C++ map of member function pointers of different classes
我试图创建一个包含不同类的成员函数指针的映射。成员函数都有相同的签名。为了做到这一点,我的所有类都继承了一个Object类,该类只有默认构造函数、虚拟析构函数和虚拟ToString() const方法。
// The map looks like this
map<Object*, void (Object::*)()> mapOfMethodPointers;
// And here are the two classes that inherit Object
// Class A
class A : public Object
{
public:
void AFunc();
string ToString() const override;
};
void A::AFunc()
{
cout << "AFunc()" << endl;
}
string A::ToString() const
{
cout << "A" << endl;
}
// Class B
class B : public Object
{
public:
void BFunc();
string ToString() const override;
}
void B::BFunc()
{
cout << "BFunc()" << endl;
}
string B::ToString() const
{
cout << "B" << endl;
}
// Here is how add the member function pointers in the map
A a;
B b;
mapOfMethodPointers[*a] = &A::AFunc;
mapOfMethodPointers[*b] = &B::BFunc;
当我在map中添加两个成员函数指针时,会得到以下错误:
- 不能转换的空白(B:: *)() ', '无效(对象::*)()
- 不能转换的空白(A:: *)() ', '无效(对象::*)()
不管类A和类B都是对象,我都不能进行这种转换。我怎样才能做到这一点呢?我需要成员函数指针的多态。我选择的实现不起作用。什么好主意吗?
为了做到这一点,我所有的类都继承了一个Object类,这个类只有默认构造函数、虚析构函数和虚ToString() const方法。
对于存储具有相似签名的多态函数来说,这是一个糟糕的解决方案。
这里有两个更好的解决方案:
1。将函数指针实现为基接口的专门化(在本例中为Object
)。然后,在客户端代码中存储接口本身:
struct Object { virtual void Execute() = 0; }
/// old: map<Object*, void (Object::*)()> mapOfMethodPointers;
/// new:
std::vector<Object*> objects;
objects[10]->Execute(); // execution is agnostic of whichever instance you you use
在这个解决方案中,Execute将解析为A::Execute
,定义如下:
class A : public Object
{
void AFunc();
public:
virtual void Execute() override { AFunc(); }
};
使用此解决方案,您不需要函数映射(因为Object
的虚表本质上是一个函数映射)。
2。用泛型函数实现函数映射,然后用lambdas填充它:
代码:/// old: map<Object*, void (Object::*)()> mapOfMethodPointers;
/// new:
map<Object*, std::function<void()>> mapOfMethodPointers;
// filling the map:
class A // not needed: public Object
{
public:
void AFunc(); // this is our interesting function
string ToString() const override;
};
A obj;
mapOfMethodPointers[&obj] = [&obj]() { obj.AFunc(); };
必须将派生成员函数强制转换为基类成员函数。它的语法有点笨拙,但完全符合逻辑。一个限制是基类不能是抽象的。
下面是一个例子:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class plant
{
public:
map<string, void(plant::*)(void)> _action;
void Action(string action);
};
void plant::Action(string action)
{
(this->*_action[action])();
}
class flower: public plant
{
public:
flower(void);
void look_at(void);
void smell(void);
void pick(void);
};
flower::flower(void)
{
_action["look at"] = (void(plant::*)(void))&flower::look_at;
_action["pick"] = (void(plant::*)(void))&flower::pick;
_action["smell"] = (void(plant::*)(void))&flower::smell;
}
void flower::look_at(void)
{
cout << "looking at flower" << endl;
}
void flower::smell(void)
{
cout << "smelling flower" << endl;
}
void flower::pick(void)
{
cout << "picking flower" << endl;
}
int main()
{
plant *myplant = new flower();
myplant->Action("look at");
myplant->Action("pick");
myplant->Action("smell");
delete myplant;
}
相关文章:
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针