2014-01-06 84 views
-1

我有下面的示例C++程序,它将指针指向类中的方法。调用该方法时出现编译器错误。调用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  } 

问题:

  1. 在行编译错误48

    ./test.cc: In member function 'void Foo::set_value(std::string, std::string)' : ./test.cc:51:35: error: must use '.*' or '->*' to call pointer-to-member function in 'temp.Foo::Bar::set_func (...)' , e.g. '(... ->* temp.Foo::Bar::set_func) (...)'

  2. 我想set_func()(其指向或者set_parm1()set_parm2())在地图更新的parmX值本身。是否有可能得到地图参数中存储的地址Bar.value(第33行)的地址,因此我可以将它传递给set_func()

    如果不是,那么我的下一个选项是什么,在地图上存储指向“Bar”的指针,而不是复制Bar。基本上使用map<string, Bar *>

  3. 只是坚持STL(不使用boost库),有没有指导方针来保存一个结构/类的ptr vs存储在地图中的整个对象。 (当然这是假设struct/class本身没有指针,也就是说在存储整个对象时不需要深度拷贝)。

谢谢
艾哈迈德。

+1

什么你不只是使用std ::函数和std ::绑定? – PlasmaHH

+0

第48行:删除* – ipinak

+1

@ipinak并删除'this->'? –

回答

3

为1:你需要把它放在括号:

(this->*temp.set_func)(value); 

为2:你可以采取的temp.value地址(你可能是Bar.value意思?),但因为它是这将是无用的一个临时变量,因此该地址在Foo的完成后无效。

对于3:我不太确定你的意思。您可以使用std::shared_ptr et。人。如果你想避免复制大型/昂贵的对象或其他手段,如移动语义来减少开销,但恐怕没有一般的答案。

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; 
} 
+0

+1注意:我只修复了编译问题,而不是你好心处理的设计问题,因此upvote :) –