以下都调用T::f
object 上的函数t
。
1. t.f();
2. t.T::f();
3. (t.*&T::f)();
我见过第二个在另一个没有的地方使用过。这两者有什么区别,在什么情况下应该首选一个?
谢谢。
编辑:对不起,我忘了第二个t.T::f()
。我把那个加进去了。
以下都调用T::f
object 上的函数t
。
1. t.f();
2. t.T::f();
3. (t.*&T::f)();
我见过第二个在另一个没有的地方使用过。这两者有什么区别,在什么情况下应该首选一个?
谢谢。
编辑:对不起,我忘了第二个t.T::f()
。我把那个加进去了。
调用t.f()
和(t.*&T::f)()
语义相同,是调用成员函数的“正常”方式。即使是被覆盖的虚函数,该t.T::f()
调用也会调用。T::f()
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()
, 是静态分派的,因此即使f
ofT
是虚拟的并且t
是T
具有自己实现的派生类,也会调用 of。它有效地抑制了虚调用机制。
第二个是没有意义的,它只是混淆的代码。不,它不会禁用虚拟调度或内联。在每种情况下,他们都做完全相同的事情。