2

考虑一个简单的例子:

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();
}

如您所见,foo在调用 bar 成员函数时可以在对象上使用范围解析,而无法显式声明成员函数指针的范围。我接受在使用时应该禁止语法,->*因为有时可能会以意想不到的方式重载运算符,但我无法理解在取消引用时阻止显式范围解析的原因.*

我正在尝试为指向基类的虚函数的成员指针禁用虚拟调度。

4

1 回答 1

5

您声明的变量的名称是foo_member,在您的本地块范围内。它不是名称Foo::foo_member,即该类Foo没有成员foo_member。相比之下,名称bar存在于类的范围内Foo,也存在于类的范围内FooParent

所以范围解析机制按预期工作:它解析了范围。

[更新:]没有通过成员函数指针禁用虚拟调度的机制。您可以像这样调用基础子对象的成员函数:

 void (FooParent::*p)() = &FooParent::bar;
 (static_cast<FooParent&>(foo).*p)();

但是电话最终仍然以虚拟方式发送。成员函数的虚拟性被烘焙到成员函数指针值中。您可以做的下一个最好的事情是使用 lambda:

auto q = [](FooParent & f) { f.FooParent::bar(); };
q(foo);
于 2016-09-21T21:39:01.183 回答