考虑一个简单的例子:
struct FooParent {
virtual void bar() { }
};
struct Foo: FooParent {
void bar() { }
};
int main() {
Foo foo;
void (Foo::*foo_member)() = &FooParent::bar;
//(foo.*FooParent::foo_member)();
foo.FooParent::bar();
}
正如您所见,当调用bar成员函数时,可以在foo
对象上使用范围解析,而无法显式声明成员函数指针的范围。我接受在使用->*
时应禁止语法,因为运算符可能会以某种意外的方式重载,但我无法理解在使用.*
解除引用时阻止显式范围解析的原因。
我正在尝试禁用指向基类的虚函数的成员指针的虚拟调度。
答案 0 :(得分:4)
您声明的变量的名称是foo_member
,位于您的本地块范围内。它不是 名称Foo::foo_member
,即类Foo
没有成员foo_member
。相比之下,名称bar
位于班级Foo
的范围内,也位于班级FooParent
的范围内。
因此,范围解析机制按预期工作:它解决了范围。
[ Update :]没有通过成员函数指针禁用虚拟分派的机制。您可以像这样调用基础子对象的成员函数:
void (FooParent::*p)() = &FooParent::bar;
(static_cast<FooParent&>(foo).*p)();
但是这个电话仍然会被虚拟派遣。成员函数的虚拟性被烘焙到成员函数指针值中。您可以做的下一件事是使用lambda:
auto q = [](FooParent & f) { f.FooParent::bar(); };
q(foo);