为什么接受成员函数指针值即使在类内部也需要类名限定?
Why does taking a member function pointer value requires class name qualification even from inside of the class?
当返回一个成员函数指针到一个类的成员函数中时,我仍然必须指定这个类。我不能简单地记下地址。例如,下面的代码工作得很好:
class Foo {
public:
void func(int param) { cout << param << endl; }
void (Foo::*getPointer())(int) { return &Foo::func; }
};
但是如果在getPointer
我尝试简单地做:return &func
我得到这个错误:
prog.cpp: In member function '
void (Foo::* Foo::getPointer())(int)
':
prog.cpp:8:43: error: ISO c++禁止接受非限定或带括号的非静态成员函数的地址来形成指向成员函数的指针。说'&Foo::func
' [-fpermissive]void (Foo::*getPointer())(int) { return &func; }
为什么我必须指定类,当那是我所在的上下文?
指针和指向成员的指针是不同的类型,我们可以从c++标准草案部分3.9.2
[basic.compound]中看到,它包括指针的复合类型以及指向非静态类成员的指针和注释:
静态类成员是对象或函数,以及指向它们的指针是指向对象或函数的普通指针
我认为这个问题在注释c++参考手册(ARM)中Johannes的回答中有很好的描述:
注意,必须显式地使用寻址操作符来获取a成员指针;没有隐式转换……如果有的话,在成员函数的上下文中,我们会有歧义…为例如,
void B::f() { int B::* p = &B::i; // ok p = B::i; // error: B::i is an int p = &i; // error: '&i'means '&this->i' // which is an 'int*' int *q = &i; // ok q = B::i; // error: 'B::i is an int q = &B::i; // error: '&B::i' is an 'int B::*' }
特别是这几行:
int B::* p = &B::i; // OK
:
p = &i; // error: '&i'means '&this->i' which is an 'int*'
说明限定名和非限定名的区别
(…有一个错误的答案…)
在以下上下文中看起来更奇怪:
class Foo {
public:
virtual void func(int param) { cout << param << endl; }
void call(int x) { Foo::func(x); }
void (Foo::*getPointer())(int) { return &Foo::func; }
};
class Bar : public Foo {
public:
void func(int param) override { cout << "Hello world!" << endl; }
};
int main() {
Foo *a = new Bar();
auto p = a->getPointer();
(a->*p)(4);
a->call(4);
return 0;
}
输出为
Hello world
4
调用Foo::func
是对Foo
类中的func
的调用,而调用&Foo::func
是虚调用。
相关文章:
- 将函数类成员映射到类本身内部
- 如何在类内部使用和访问静态指针到成员值s_ptm?
- 是否允许分配器构造和销毁成员函数从内部逻辑引发异常?
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 返回自身内部的双重嵌套类的成员函数,该类继承自从自身继承的类
- 指向C++中成员的指针如何在内部工作?
- 我如何从循环内部使用迭代器的函数内部的getter中检索特定的成员
- 结构内部的结构:"对非静态成员的非法引用"错误
- 从对象成员函数内部删除操作的技术 /设计模式
- 班级成员在C Lambdas中捕获内部构造函数
- 在成员函数内部调用成员函数
- 如何在类构造函数内部对同一类的成员函数启动pthread
- 类(模板)成员函数体内部的ADL查找
- 如何在c++中实现内部抽象成员类
- 在类中带有来自另一个类的成员函数的类内部线程
- 另一个结构内部的结构数组的成员变量没有通过引用传递
- 类中的内部成员可见性
- 正在获取成员函数内部成员函数的地址
- c++/cli仅向托管类公开内部成员
- 私有内部成员的操作符重载