有人可以就此问题向我提出想法。我已经在互联网上搜索过这个,但是没有得到我想要的更多信息。
说有一个班级。
class Foo {
explicit Foo() {}
int getVar1();
int getVar2();
void setVar1(int v);
void setVar2(int v);
private:
int var1, var2;
};
现在给出一个令牌列表{“var1”,“var2”,...“varN”},有没有什么方法可以在运行时创建函数名称并调用某些Foo类型对象的成员函数。比如像
Foo obj;
string input = "Var1,Var2,Var3,...VarN";
vector<string> tokens = splitString(input);
for (vector<string>::const_iterator it = tokens.begin(); it != tokens.end(); ++it) {
string funName = "get" + *it;
// somehow call obj.getVar1()....obj.getVarN()
}
使用if else对于少量变量是好的,但它对大量变量不好。使用bind和functor也无法解决这个问题。一个网页建议在运行时使内存可执行,然后使用reinterpret_cast,我不知道这是否可行。
更新
好的,从互联网上的答案和其他搜索来看,我发现在C ++中没有优雅的方法。到目前为止,C ++中没有任何反映。所有黑客都需要成员函数指针的编译时解析。 当你有很多变量和setter和getters函数时,有人可以给我一些关于替代类设计的想法吗?或者getter和setter在c ++中是不是很好用?
答案 0 :(得分:4)
作为一个想法考虑以下代码
struct A
{
void f1() { std::cout << "A::f1()\n"; }
void f2() { std::cout << "A::f2()\n"; }
void f3() { std::cout << "A::f3()\n"; }
void f4() { std::cout << "A::f4()\n"; }
};
std::map<std::string, void( A::* )()> m = { { "f1", &A::f1 }, { "f2", &A::f2 }, { "f3", &A::f3 }, { "f4", &A::f4 } };
A a;
for ( auto p : m ) ( a.*p.second )();
您可以将地图设为班级的数据成员。
答案 1 :(得分:2)
您无法在运行时“添加”成员。 C ++在编译时是强类型的。
您可以通过拥有map<string, func_type>
并使用它将字符串解析为实际函数来获得所需的行为。您可以使用宏来创建它,以确保字符串名称与函数名称匹配。
#DEFINE ADD_METHOD(map_var, func) map_var["func"] = &func
答案 2 :(得分:0)
一个简单/不完美的解决方案可能是使用中间方法检查参数并相应地调用getVar *方法。
像这样的例子可能是:
class Foo
{
public:
explicit Foo() {}
int getVar1() { return 1; }
int getVar2() { return 2; }
void setVar1(int v) { var1 = v; }
void setVar2(int v) { var2 = v; }
int callGetVar(const std::string &var)
{
if (var == "Var1") return getVar1();
if (var == "Var2") return getVar2();
else { return -1; }
}
private:
int var1, var2;
};
int main()
{
Foo obj;
std::string input = "Var1,Var2,Var3,...VarN";
std::vector<std::string> tokens = { "Var1", "Var2", "Var2", "Var1", "Var1", "Var2", "Var2", "Var1"};
auto tokensIT = tokens.begin();
for (; tokensIT != tokens.end(); ++tokensIT)
{
// somehow call obj.getVar1()....obj.getVarN()
std::cout << obj.callGetVar(*tokensIT);
}
return 0;
}
答案 3 :(得分:0)
为什么不以指示的方式看待它: 为每个变量分配一个索引号,从0,1,2开始.... 您将此值保留在映射中(键是变量名称,值是指定的值)。 这些变量的所有值都保存在一个数组中,以便第一个变量的值在单元格0中,下一个变量在单元格1中等。
所以,当你想得到/设定值时,你需要做的就是在地图中找到它的索引,并访问向量中的相关单元格。