不同的行为:直接调用函数与通过非静态成员指针调用函数
Different Behaviour: Calling Function Directly vs. Through non-static member pointer
问题:
虽然我知道函数指针,但我不明白是什么让这两个函数在Derived
类中有不同的作用:
I( StartPrintThroughFuncPtr()
II( StartPrint()
这是完整代码,加上注释中的输出:
#include "iostream"
class Base
{
(void)(Base::*callee)(void);
virtual void Print(){std::cout<<"Print: Base"<<std::endl;}
public:
void StartPrintThroughFuncPtr(){
callee = &Base::Print;
(this->*callee)();
}
void StartPrint(){
Base::Print();
}
};
class Derived : public Base
{
virtual void Print(){std::cout<<"Print: Derived"<<std::endl;}
};
void main()
{
Base *basePtr = new Base;
basePtr->StartPrintThroughFuncPtr(); // ==> "Print: Base"
basePtr->StartPrint(); // ==> "Print: Base"
Derived *derivedPtr = new Derived;
derivedPtr->StartPrintThroughFuncPtr(); // ==> "Print: Derived"
derivedPtr->StartPrint(); // ==> "Print: Base"
}
感谢=(
指向虚拟函数的指针实际上在虚拟函数表中存储偏移量,而不是指向函数的直接指针。这就是为什么通过它调用是虚拟的。
指向成员函数的指针支持多态行为。当您创建一个指向虚拟函数的指针时,调用会被调度到基于调用该函数的对象的运行时类型的实现(在您的情况下,是basePtr
或derivedPtr
(。作用域解析运算符在那里并不重要,因为指向虚拟函数的函数指针并没有完全定义目标。
C++11标准,第4.11.2节:类型为"cv T类型的B的成员的指针"的prvalue,其中B是类类型,可以转换为类型为"CVT类型的D的成员的指示器"的prvalue,其中D是B的派生类(第10条(,但是它引用基类成员,就好像它是派生类的成员一样(强调(
另一方面,StartPrint
通过其范围解析操作符直接调用Base
类中的实现。
相关文章:
- 如何用参数值调用函数(仅在运行时已知)
- 从python中调用C++函数并获取返回值
- 当使用通配符和null指针调用函数时,对输出的说明
- 从R调用C++函数并对其进行集成时出错
- 使用QTreeView,如何通过调用函数只突出显示特定的行/列
- 如何在qt中从另一个类调用函数
- 在 COUT 语句中使用 COUT 调用函数
- 如何从线程中的不同模块调用函数?
- C++从函数指针数组调用函数
- 当 A 在 for 循环中调用函数 B 时,如何计算函数 A 的空间复杂度?
- 如何在 C/C++ 中从外部库调用函数
- 如何使用运算符在同一行中多次调用函数
- 是否可以创建一个从不同类调用函数的线程?
- 无法为类成员调用函数
- 如何从另一个标头 c++ 调用函数
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 如何只允许在调用函数 B 后调用函数 A?
- 我可以这样调用函数吗?
- 如何在 c++ 的类中递归调用函数方法?
- 为什么在指向对象的迭代器上调用函数不允许我更改对象本身?