c ++标准(ISO c ++ 11)在第9.3.1节中提及
可以为其类的对象调用非静态成员函数 类型,或从类中派生的类的对象(第10条) 类型,使用类成员访问语法(5.2.5,13.3.1.1)。
尝试使用g ++(版本4.8.2)
编译此代码 class foo{
public:
void bar(){
cout<<"hey there"<<endl;
}
};
int main(){
foo obj;
foo::bar(&obj);
}
给出编译时错误,因为它无法匹配函数的签名。鉴于调用成员函数的标准陈述,我想这是预期的。 由于该方法最终会在编译的某个阶段采用类似于 bar(foo *)的形式,为什么标准要求成员访问语法调用成员函数?
答案 0 :(得分:7)
让我们将 static 成员添加到类中:
class foo{
public:
void bar() { cout<<"hey there"<<endl; }
static void bar(foo*) { cout<<"STATIC MEMBER"<<endl; }
};
现在,如果你这样写:
foo::bar(&obj); //static or non-static?
应该调用哪个函数?在这种情况下,您如何调用两者?语法是什么?如果允许一个函数具有此语法,则必须放弃它(即语法)以获取其他函数。标准决定为static
成员函数使用 foo :: bar(&amp; obj)语法,同时放弃非静态成员函数。
无论如何,如果你想将&obj
作为参数传递给非静态成员函数,那么你可以使用由std::function
促成的类型擦除作为:
void (foo::*pbar)() = &foo::bar; //non-static member function #1
std::function<void(foo*)> bar(pbar);
bar(&obj); //same as obj.bar();
同样,您可以将静态成员函数称为:
void (*pbar)(foo*) = &foo::bar; //static member function #2
std::function<void(foo*)> bar(pbar);
bar(&obj); //same as foo::bar(&obj);
请注意,在行#1
和#2
处,对象pbar
的类型使编译器选择正确的成员函数 - 在第一种情况下,它将指针指向非静态成员函数,而在后一种情况下,它将指针指向 static 成员函数。
希望有所帮助。