| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> c++对象模型 -> 正文阅读 |
|
[C++知识库]c++对象模型 |
整理:侯捷老师的《面向对象高级编程》(下) 理解对象模型,才能真正理解多态和动态绑定. 1 成员函数和成员变量在内存中的分布下面程序在内存中的布局如下所示:
代码很简单,继承也很清晰。 其在内存中的布局如下图所示:【这个图是精髓】 ?下面来解释一下这个图: 1?A内存结构:下图中用红框框起来。 ? 对于A而言,其内存有两个数据成员:m_data1、m_data2,这是占类的大小的。 还有两个虚函数:virtual void vfunc1()和virtual void vfunc2()。那么虚函数在类中的内存分布是怎 样的呢? 首先,对于每个含有虚函数的类,系统都会自动生成虚函数表(简称虚表vtbl),虚表中存储A类中的每个虚函数的函数指针;然后,在A类实例化对象时,对象地址的前4个(32位机器)字节存储指向虚表的指针,简称虚指针(vptr)。 所以,对于A类而言,初始化对象时,内存中有两个数据成员和一个虚指针(虚指针指向虚表,虚表存储的是两个虚函数的地址)。 2?B的内存结构:下图用红框框起来 ?B类继承了A类,那么它就有A类的数据成员和成员函数,所以它的数据域有从A类继承的m_data1 和m_data2,还有自己的数据m_data3;它又实现A类中的虚函数vfunc1,自己还有一个func2函 数,这个函数不是虚函数,是非静态函数,不占内存。 所以,对于B类而言,初始化对象时,内存中有三个数据成员(两个父类的,一个自己的),一个 虚指针(虚指针指向虚表,虚表中存储的是自己重写的vfunc1函数的地址和继承父类A的虚函数 vfunc2的地址)。 3?C的内存结构:下图用红框框起来 C类的分析和B类的分析一样,只是还要多考虑A类 C类继承了B类,那么它就有B中的数据成员和成员函数,所以它的数据域有m_data1、m_data2(这两个是从A类继承来的)、m_data3(从b类继承来的)、m_data4(自己的);它又实现了B类的虚函数vfunc1,还有一个自己的不占内存的非静态函数func2。 所以,对于C类而言,初始化对象时,内存中有四个数据成员(A类的两个、B类的一个、自己的一个),一个虚指针(虚指针指向虚表,虚表中存储C类重写的vfunc1函数的地址和继承父类的虚函数vfunc2函数的地址)。
更为一般的多态的过程: (1)编译器在发现基类中有虚函数时,会自动为每个含有虚函数的类生成一份虚表,该表是一个一维数组,虚表里保存了虚函数的入口地址; (2)编译器会在每个对象的前四个字节中保存一个虚表指针,即vptr,指向对象所属类的虚表。在构造时,根据对象的类型去初始化虚指针vptr,从而让vptr指向正确的虚表,从而在调用虚函数时,能找到正确的函数; (3)所谓的合适时机,在派生类定义对象时,程序运行会自动调用构造函数,在构造函数中创建虚表并对虚表初始化。在构造子类对象时,会先调用父类的构造函数,此时,编译器只“看到了”父类,并为父类对象初始化虚表指针,令它指向父类的虚表;当调用子类的构造函数时,为子类对象初始化虚表指针,令它指向子类的虚表; (4)当派生类对基类的虚函数没有重写时,派生类的虚表指针指向的是基类的虚表;当派生类对基类的虚函数重写时,派生类的虚表指针指向的是自身的虚表;当派生类中有自己的虚函数时,在自己的虚表中将此虚函数地址添加在后面; 这样指向派生类的基类指针在运行时,就可以根据派生类对虚函数重写情况动态的进行调用,从而实现多态性。 2?静态绑定和动态绑定
静态绑定和动态绑定编译出的汇编代码如下所示: ? 虚函数触发动态绑定的条件是同时满足以下3个条件:
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 22:08:17- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |