调用方法的这三种语法形式之间有什么区别?

What's the difference between these three forms of syntax for calling a method?

本文关键字:之间 什么 区别 语法 三种 方法 调用      更新时间:2023-10-16

下面两个都在对象t上调用函数T::f

1. t.f();
2. t.T::f();
3. (t.*&T::f)();

我看到第二个被用在另一个没有的地方。这两者之间的区别是什么?在什么情况下应该优先使用其中一种?

谢谢。

EDIT:对不起,我忘记了第二个t.T::f()

调用t.f()(t.*&T::f)()在语义上是相同的,并且是调用成员函数的"正常"方式。即使f()是一个被覆盖的虚函数,调用t.T::f()也会调用T::f()

表达式(t.*&T::f)()通过获取成员函数的指针来调用成员函数。该表达式可能具有的唯一潜在影响是,它可能会禁止对某些编译器内联函数。使用从&T::f获得的变量来调用成员函数将是一个定制点,但直接调用函数仅仅是混淆和潜在的悲观(如果编译器不能做足够的const传播来检测地址不能更改)。

我可以想象是有人试图抑制t上的虚函数调用。当然,这不是这样工作的,因为指向成员的指针仍然会调用正确的虚函数。要禁止虚拟调度,可以使用t.T::f()

你应该更喜欢t.f()而不是(t.*&T::f)()。如果你想禁止虚拟调度,你可以使用t.T::f(),否则你可以使用t.f()。抑制虚拟分派的主要用途是从重写函数内部调用函数的基类版本。

第一个是常规的,这是你应该选择的。第二个函数接受一个指向f成员函数指针,为t解引用它,然后调用它。

如果额外的旅行有什么实际的好处,我不知道。这是*&f()在调用自由函数时的成员版本。

您稍后添加的t.T::f()静态调度的,因此即使Tf是虚拟的,t也是T的派生类,并且具有自己的实现,也会调用它。

第二个是没有意义的,它只是混淆了代码。不,它不会禁用虚拟调度和内联。