2011-11-26 74 views
2

在我的课,如果我想指向类的成员,指向类的成员

struct S 
{ 
    static int get(); 
    int do_something(); 
    int x; 
}; 

我这样做,

int (*p)() = S::get; 

不幸的是这并不适用于非静态成员

int (*p)() = S::do_something; // error 

因为,静态成员函数是一个普通的功能,从我来到下方围绕该帖指出,非静态成员函数的n也是一个普通的函数,为什么它不起作用?这是什么意思?

(9.2/10)[注:一个非静态成员函数的类型是普通 功能类型和非静态数据成员的类型是一个普通的 对象类型。没有特殊的成员函数类型或数据成员 类型。 ]

+1

这是在这里回答:http://stackoverflow.com/questions/439540/function-pointer-to-class-member-function-problems –

+1

必须阅读理解的概念:[指向成员函数](http ://www.parashift.com/c++-faq-lite/pointers-to-members.html) –

回答

2

函数的类型是普通的,而不是函数指针的类型。一个指向非静态成员函数必须声明如下:

typedef int (S::*p)() ptr_to_member_of_s; 
5

非静态成员函数普通函数。你不能形成免费的指针。

唯一允许的方式来指代非静态成员功能是通过一个实例的指针/参考的和一个指针到成员函数:

S * p = &theobject; 
int (S::*ptmf)() = &S::do_something; 

return (p->*ptmf)(); 

不同于构件对象(你可以非常好地形成一个空闲指针,例如&theobject.x),成员函数更加复杂,因为你需要考虑虚拟函数:如果S是一个多态基类,并且p是一个指针指针,并且do_something()是虚拟的,那么上面的例子应该执行正确的派遣类型。一个简单的免费函数指针不能做到这一点。

(此外,该标准未规定如何的成员函数每个底层实现实现的,所以这个细节不会暴露给用户。通常它会像int S_mangled_name_do_something(S *);,但没有指定真实。)

这里是我的主题的一些相关答案:#1,#2

0
int (S::*p)() = S::do_something; 

非静态成员函数是一个普通的函数,只是有一个不可见的参数this。

+0

不可见参数只是冰山一角。虚拟调度是一个更严重的设计问题。 –

+0

@KerrekSB同意。对于虚函数,我们可以在Lambda表达式中使用std :: function:Base * p =&theObject; \t std :: function func = [&p]() - > int { \t \t return p-> doSomething(); \t};' – BruceAdi

+1

否否否 - '(p - > * ptfm)()'已经处理了正确的分派。我的观点是成员函数不仅仅是一个带有隐藏参数的自由函数。 –