调用方法的这三种语法形式之间有什么区别?
What's the difference between these three forms of syntax for calling a method?
下面两个都在对象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()
是静态调度的,因此即使T
的f
是虚拟的,t
也是T
的派生类,并且具有自己的实现,也会调用它。
第二个是没有意义的,它只是混淆了代码。不,它不会禁用虚拟调度和内联。
相关文章:
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 这 4 个 lambda 表达式之间有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 不同的类或结构初始化方法之间的性能差异是什么?
- "constinit"和"constexpr"之间的真正区别是什么?
- 在什么条件下使用 std::memcpy 在对象之间复制是安全的?
- 移动语义和深层/浅层复制之间有什么关系?
- 这两种C++语法之间有什么区别?
- #include < conio.h> 和 getch() 方法之间的关系是什么?
- ((int) a) 和 (int(a)) 之间的区别是什么?
- ( var > x) 和 ( x < var)之间有什么区别吗?
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 超市管理系统的类别之间应该是什么关系?
- 指针和程序性能之间有什么关系吗?
- 这些初始化之间有什么区别?
- 空字符和"\0"之间有什么区别?
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?