基类为什么不能调用派生类的方法

本文阐述了在C++中虚拟函数与普通函数在编译器处理方式上的区别,包括晚绑定与早绑定的概念,以及如何通过虚函数实现多态性。

andy_cai如是说:
首先有每个派生类都有自己的虚函数表

其次,对虚函数编译器是晚绑定的
所以能正确调用指定对象的函数

而对普通函数,编译器是早绑定的
等能检查到实际指定对象时,已经指向了基类的函数
而且编译器此时也不会去做判断
adintr如是说:
对指针转型不会发生切割,不会改变指向的内容。

这里的一个主要区别是一个编译时和运行时的问题。
虚函数的调用是运行时的,只有当程序运行到此处时指针内容确定后才能确定这次调用的是哪个函数。

而普通函数的调用是编译时就确定的,编译看到一个基类指针的时候并不知道这个指针的内容,只知道他的类型。所以他并不知道它指向的是哪个派生类,自然也就不知道这些派生类的方法。你调用一个派生类的方法后编译器无法找到这个函数的地址。

转http://bbs.youkuaiyun.com/topics/220047733

### C++ 中基类指针调用派生类虚函数的多态机制工作原理 在 C++ 的面向对象编程中,基类指针能够通过动态绑定调用派生类中的虚函数,这是由于 **虚函数表(vtable)** 和 **虚函数指针(vptr)** 的存在所决定的。 #### 虚函数表的作用 当一个类定义了虚函数时,在编译期间会为该类创建一张虚拟函数表(简称 vtable)。这张表是一个一维数组,存储着所有虚函数的地址。对于每一个具有虚函数的类实例来说,其内存布局会在最前面分配一段空间用于保存指向对应 vtable 的指针(即 vptr)。因此,无论基类还是派生类,只要涉及虚函数,都会生成相应的 vtable 并设置好对应的 vptr[^3]。 #### 动态绑定过程解析 假设有一个基类 `Base` 和它的派生类 `Derived`,其中两者均含有同名虚函数 `virtual void func()`: 1. 当创建了一个派生类对象并让基类类型的指针指向它时,虽然表面上看是指向的是基类部分,但实际上整个完整的派生类对象仍然存在于内存之中; 2. 此刻如果经由该基类指针调用被标记成 virtual 的方法,则程序并不会简单依据当前静态类型来定位具体实现版本——而是借助之前提到过的 vptr 来完成最终的目标选择操作; 3. 运行时刻,系统利用此基类指针间接获取到实际关联的那个真实实体内部维护好的 vptr 所指示的位置信息,并据此查找到真正应该被执行的方法入口位置从而达成预期效果 —— 即实现了所谓的 “运行期多态”。 以下是简单的代码演示这一概念: ```cpp #include <iostream> using namespace std; class Base { public: virtual void whoAmI() { cout << "I am base class." << endl; } }; class Derived : public Base { public: void whoAmI() override { cout << "I am derived class." << endl; } // Override the function from Base. }; int main(){ Base* bPtr; Derived dObj; bPtr = &dObj; // A pointer of type 'Base' points to an object of type 'Derived'. bPtr->whoAmI(); // Output will be: I am derived class. return 0; } ``` 上述例子展示了即使我们使用的是基类类型的指针 `bPtr` ,但由于采用了动态联编技术的缘故,最后执行的结果却是来自派生类里的覆写的那个版本的行为表现出来。 #### 关键点总结 - 只要满足两个条件就可以触发动态多态行为:一是存在继承关系;二是子类确实重新定义(override)了父类里已声明为 virtual 类型的功能模块。 - 基于以上设定下,即便采用基础类别视角下的接口形式进行交互处理动作发起请求,也能正确无误地映射至目标衍生个体所提供的个性化服务上去落实相应逻辑流程运转起来[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值