我有以下示例C ++程序,它隐藏了指向类中方法的指针。调用该方法时出现编译器错误。
10 class Foo
11 {
12 void set_parm1(string) {}
13 void set_parm2(string) {}
14
15 typedef void (Foo::*set_func_t)(string);
16 struct Bar
17 {
18 string value;
19 set_func_t set_func;
20 };
21
22 map<string, Bar> parameter;
23
24 public:
25 Foo();
26 void set_value(string key, string value);
27 };
28
29 Foo::Foo()
30 {
31 Bar temp;
32
33 temp.value = "value1";
34 temp.set_func = &Foo::set_parm1;
35 parameter["param1"] = temp;
36
37 temp.value = "value2";
38 temp.set_func = &Foo::set_parm2;
39 parameter["param1"] = temp;
40 }
41
42 void
43 Foo::set_value(string key, string value)
44 {
45 Bar temp;
46
47 temp = parameter[key];
48 this->*temp.set_func(value);
49 }
问题:
第48行的编译器错误
./ test.cc:在成员函数
'void Foo::set_value(std::string, std::string)'
中: ./test.cc:51:35:错误:必须使用'.*'
或'->*'
来调用'temp.Foo::Bar::set_func (...)'
中的指针指向成员函数,例如'(... ->* temp.Foo::Bar::set_func) (...)'
我希望set_func()
(指向set_parm1()
或set_parm2()
)更新地图中parmX
的值。我是否有可能获得存储在map参数中的Bar.value
(第33行)地址,因此我可以将其传递给set_func()
?
如果不是,那么我的下一个选项是什么,在地图中存储指向“Bar”的指针,而不是Bar的副本。基本上使用map<string, Bar *>
。
坚持使用STL(不使用boost库),是否存在将ptr保存到struct / class与将整个对象存储在map中的指南。 (当然这是假设struct / class本身没有指针,也就是说在存储整个对象时不需要深层复制)。
谢谢你,
艾哈迈德。
答案 0 :(得分:4)
For 1:你需要把它放在括号中:
(this->*temp.set_func)(value);
For 2:你可以取temp.value
的地址(你可能是Bar.value
的意思?),但这是无用的,因为它是一个临时变量,因此在{之后地址无效{1}}完成了。
对于3:我不确定你的意思。您可以使用Foo
et。人。如果你想避免复制大型/昂贵的对象或其他手段,如移动语义,以减少开销,但我不担心一般的答案。
答案 1 :(得分:2)
@Daniel Frey建议的解决方案可能会奏效。
但是在C ++(或任何其他面向对象的语言)中使用多态的正确方法。
在技术方面,您需要做的是考虑使用继承与虚函数结合而不是函数指针。
例如(根据您提问中的代码):
class Foo
{
protected:
virtual void set_parm(string)=0;
struct Bar
{
string value;
};
map<string, Bar> parameter;
public:
void set_value(string key, string value);
};
class Foo1 : public Foo
{
private:
void set_parm(string) {} // you probably wanna do something here...
public:
Foo1();
};
class Foo2 : public Foo
{
private:
void set_parm(string) {} // you probably wanna do something here...
public:
Foo2();
};
void Foo::set_value(string key, string value)
{
Bar temp;
temp = parameter[key];
set_parm(value);
}
Foo1::Foo1()
{
Bar temp;
temp.value = "value1";
parameter["param1"] = temp;
}
Foo2::Foo2()
{
Bar temp;
temp.value = "value2";
parameter["param1"] = temp;
}