IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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++内存分析,单继承,多继承,虚继承,菱形继承

hh 现在就不贴代码了 太长了
就贴点文字和图片

c++难的点估计就是概念 内存模型哪些太多了。。。

1.函数易混淆概念

概念区分
	-函数重载
	-函数覆盖
	-函数隐藏
    
函数重载
	-1.同作用域
	-2.函数名相同,参数列表不同(参数个数,参数顺序,参数类型)
	-3.返回值和调用约定 无关 也与virtual无关
	-4.成员函数中const也会构成重载,因为普通的成员函数的this指针是指针常量,而有const的是常量指针常量    
    
函数覆盖(多态,虚函数) - 子类中重写的虚函数覆盖虚表中父类的虚函数对应项	
	-1.函数声明【函数名,参数列表,返回值等】要一致(子类中的函数和父类中的函数)
	-2.父类函数要有virtual关键字,子类可以有可以没有   
    
函数隐藏-子类的名字隐藏父类的名字
	-1.函数名一样,参数列表,返回值类型,调用约定不做考虑
注意:如果函数声明一样,并且父类有virtual关键字,则构成函数覆盖  

image-20211223153737186

image-20211223153946564

image-20211223154238524

image-20211223154307556

image-20211223154433473

image-20211223154516723

image-20211223154715909

2.内存结构分析

-没有虚继承的情况

1.单个类
|*************|
|成员变量1     |
|成员变量2     |
|成员变量...   |
|*************|
    
2.单个类有虚函数
|*************|     __vftable   |**************|
|虚函数指针     | -----> 虚函数表   |虚函数地址1     |
|成员变量1     |                  |虚函数地址2     |
|成员变量2     |                  |虚函数地址...   |
|成员变量...   |				  |**************|			
|*************|
    
3.单继承
|*****************|
|父类成员变量1      |
|父类成员变量2      |
|父类成员变量...    |
|子类成员变量1      |
|子类成员变量2      |
|子类成员变量...    |
|*****************|
    
4.单继承有虚函数
|*****************|       __vftable   |**************|
|虚函数指针         |  -----> 虚函数表   |虚函数地址1     |
|父类成员变量1      |					  |虚函数地址2     |
|父类成员变量2      |					  |虚函数地址...   |
|父类成员变量...    |					  |**************|
|子类成员变量1      |
|子类成员变量2      |
|子类成员变量...    |
|*****************|
    
5.多继承
【如果父类没有虚函数,则没有虚表和虚表指针】
|*****************************|
|第一个继承单父类成员变量1        |
|第一个父类成员变量2             |
|第一个父类成员变量...           |
|第二个继承单父类成员变量1        |
|第二个父类成员变量2             |
|第二个父类成员变量...           |
|............................ |
|子类成员变量1                  |
|子类成员变量2                  |
|子类成员变量...                |
|*****************************|

6.多继承有虚函数
【如果两个父类都有虚函数,如果只有一个父类有虚函数,那么虚函数指针就只有一个,以此类推】
【如果子类重写了父类的虚函数,不会增加多的虚表指针,而是直接把父类虚表对应的项修改】
【如果子类不是重写父类的虚函数,而是自己有虚函数,也是直接对父类的虚表进行修改,一般放在第一个虚表中】
|*****************************|     __vftable    |**************|
|虚函数指针                     | -----> 虚函数表    |虚函数地址1    |
|第一个继承单父类成员变量1         |                  |虚函数地址2    |
|第一个父类成员变量2              |                  |虚函数地址...  |
|第一个父类成员变量...            |     __vftable    |**************|
|虚函数指针                     | -----> 虚函数表    |**************|
|第二个继承单父类成员变量1         |				  |虚函数地址1     |
|第二个父类成员变量2              |				    |虚函数地址2     |
|第二个父类成员变量...            |				    |虚函数地址...   |
|............................ |	................ |***************|
|子类成员变量1                   |
|子类成员变量2                   |
|子类成员变量...                 |
|*****************************|
    
-有虚继承的情况
    
1.单虚继承
|*****************|               |******************************|
|偏移块指针         | -----> 偏移块  |0x00000000                    |
|本类成员变量1      |               |对象首地址到虚基类的偏移地址       |
|本类成员变量2      |               |******************************| 
|本类成员变量...    | 
|虚基类成员变量1    |					
|虚基类成员变量2    |					
|虚基类成员变量...  |					
|*****************|

2.单虚继承有虚函数
【如果子类没有虚函数,或者只对父类的虚函数进行了覆盖】
|*****************|               |******************************|
|偏移块指针         | -----> 偏移块  |偏移块地址到虚表指针的距离        |
|本类成员变量1      |               |偏移块地址到虚基类的偏移地址       |
|本类成员变量2      |               |******************************|
|本类成员变量...    |     __vftable 
|虚表指针          | -----> 虚函数表    |**************|
|虚基类成员变量1    |					 |虚函数地址1   |
|虚基类成员变量2    |					 |虚函数地址2   |
|虚基类成员变量...  |				     |虚函数地址... |
|*****************|					 |**************|


【如果子类有自己的虚函数】
|*****************|                 |******************************|    |**************|
|虚表指针          | -----> 虚函数表   |偏移块地址到虚表指针的距离        |     |虚函数地址1   |
|偏移块指针        | -----> 偏移块     |偏移块地址到虚基类的偏移地址      |     |虚函数地址2   |
|本类成员变量1      |                 |******************************|	 |虚函数地址... |
|本类成员变量2      |													    |**************|
|本类成员变量...    |     __vftable
|虚表指针          | -----> 虚函数表   |**************|
|虚基类成员变量1    |					| 虚函数地址1   |
|虚基类成员变量2    |					| 虚函数地址2   |
|虚基类成员变量...  |				    | 虚函数地址... |
|*****************|					|**************|
    
3.菱形继承                                       
|********************************|               |******************************|  
|第一个继承的父类的偏移块地址         | -----> 偏移块  |偏移块地址到虚表指针的距离        |
|第一个继承的父类的成员变量1         |               |偏移块地址到虚基类的偏移地址       |
|第一个继承的父类的成员变量2         |               |******************************|
|第一个继承的父类的成员变量...       | 			    
|第二个继承的父类的偏移块地址        | -----> 偏移块  |******************************| 
|第二个继承的父类的成员变量1         |			    |偏移块地址到虚表指针的距离        |
|第二个继承的父类的成员变量2         |			    |偏移块地址到虚基类的偏移地址       |
|第二个继承的父类的成员变量...       |			    |******************************|
|.............................   |
|本类的成员变量1                   |	
|本类的成员变量2                   |	
|本类的成员变量....                |	
|虚基类成员变量1                   |					 
|虚基类成员变量2                   |					 
|虚基类成员变量...                 |				     
|*******************************|					 

4.菱形继承有虚函数
【子类自己拥有虚函数并不会增加虚表指针,而是直接在虚基类的虚表中进行了修改】
|*******************************|                 |******************************|    |**************|
|第一个继承的父类的虚函数指针        | -----> 虚函数表  |偏移块地址到虚表指针的距离         |    |虚函数地址1    |
|第一个继承的父类的偏移块地址        | -----> 偏移块    |偏移块地址到虚基类的偏移地址       |    |虚函数地址2    |
|第一个继承的父类的成员变量1        |				  |******************************|	  |虚函数地址...  |
|第一个继承的父类的成员变量2        |				                                      |**************|
|第一个继承的父类的成员变量..        |				  |******************************|	  |************ |   
|第二个继承的父类的虚函数指针       | -----> 虚函数表    |偏移块地址到虚表指针的距离        |    |虚函数地址1    |
|第二个继承的父类的偏移块地址       | -----> 偏移块      |偏移块地址到虚基类的偏移地址      |    |虚函数地址2    |
|第二个继承的父类的成员变量1        |   				  |******************************|	  |虚函数地址...  |
|第二个继承的父类的成员变量2        |   				                                      |**************|
|第二个继承的父类的成员变量...      |
|.............................  |
|本类的成员变量1                  |
|本类的成员变量2                  |
|本类的成员变量....               |				   |**************|	
|虚基类的虚函数指针                | -----> 虚函数表    |虚函数地址1    |
|虚基类成员变量1                  |				   |虚函数地址2    |
|虚基类成员变量2                  |			       |虚函数地址...  |
|虚基类成员变量...                |				   |**************|
|*******************************|    

2.1-没有虚继承的情况

1.单个类
|*************|
|成员变量1     |
|成员变量2     |
|成员变量...   |
|*************|

image-20211223155418950

2.单个类有虚函数
|*************|     __vftable   |**************|
|虚函数指针     | -----> 虚函数表   |虚函数地址1     |
|成员变量1     |                  |虚函数地址2     |
|成员变量2     |                  |虚函数地址...   |
|成员变量...   |				  |**************|			
|*************|

image-20211223155602268

3.单继承
|*****************|
|父类成员变量1      |
|父类成员变量2      |
|父类成员变量...    |
|子类成员变量1      |
|子类成员变量2      |
|子类成员变量...    |
|*****************|

image-20211223155713515

4.单继承有虚函数
|*****************|       __vftable   |**************|
|虚函数指针         |  -----> 虚函数表   |虚函数地址1     |
|父类成员变量1      |					  |虚函数地址2     |
|父类成员变量2      |					  |虚函数地址...   |
|父类成员变量...    |					  |**************|
|子类成员变量1      |
|子类成员变量2      |
|子类成员变量...    |
|*****************|

image-20211223155849307

5.多继承
【如果父类没有虚函数,则没有虚表和虚表指针】
|*****************************|
|第一个继承单父类成员变量1        |
|第一个父类成员变量2             |
|第一个父类成员变量...           |
|第二个继承单父类成员变量1        |
|第二个父类成员变量2             |
|第二个父类成员变量...           |
|............................ |
|子类成员变量1                  |
|子类成员变量2                  |
|子类成员变量...                |
|*****************************|

image-20211223160040377


6.多继承有虚函数
【如果两个父类都有虚函数,如果只有一个父类有虚函数,那么虚函数指针就只有一个,以此类推】
【如果子类重写了父类的虚函数,不会增加多的虚表指针,而是直接把父类虚表对应的项修改】
【如果子类不是重写父类的虚函数,而是自己有虚函数,也是直接对父类的虚表进行修改,一般放在第一个虚表中】
|*****************************|     __vftable    |**************|
|虚函数指针                     | -----> 虚函数表    |虚函数地址1    |
|第一个继承单父类成员变量1         |                  |虚函数地址2    |
|第一个父类成员变量2              |                  |虚函数地址...  |
|第一个父类成员变量...            |     __vftable    |**************|
|虚函数指针                     | -----> 虚函数表    |**************|
|第二个继承单父类成员变量1         |				  |虚函数地址1     |
|第二个父类成员变量2              |				    |虚函数地址2     |
|第二个父类成员变量...            |				    |虚函数地址...   |
|............................ |	................ |***************|
|子类成员变量1                   |
|子类成员变量2                   |
|子类成员变量...                 |
|*****************************|

image-20211223160241010

image-20211223160432443

2.2-有虚继承的情况

1.单虚继承
|*****************|               |******************************|
|偏移块指针         | -----> 偏移块  |偏移块地址到虚表指针的距离                   |
|本类成员变量1      |               |对象首地址到虚基类的偏移地址       |
|本类成员变量2      |               |******************************| 
|本类成员变量...    | 
|虚基类成员变量1    |					
|虚基类成员变量2    |					
|虚基类成员变量...  |					
|*****************|

image-20211223202944961

2.单虚继承有虚函数
【如果子类没有虚函数,或者只对父类的虚函数进行了覆盖】
|*****************|               |******************************|
|偏移块指针         | -----> 偏移块  |偏移块地址到虚表指针的距离        |
|本类成员变量1      |               |偏移块地址到虚基类的偏移地址       |
|本类成员变量2      |               |******************************|
|本类成员变量...    |     __vftable 
|虚表指针          | -----> 虚函数表    |**************|
|虚基类成员变量1    |					 |虚函数地址1   |
|虚基类成员变量2    |					 |虚函数地址2   |
|虚基类成员变量...  |				     |虚函数地址... |
|*****************|					 |**************|


【如果子类有自己的虚函数】
|*****************|                 |******************************|    |**************|
|虚表指针          | -----> 虚函数表   |偏移块地址到虚表指针的距离        |     |虚函数地址1   |
|偏移块指针        | -----> 偏移块     |偏移块地址到虚基类的偏移地址      |     |虚函数地址2   |
|本类成员变量1      |                 |******************************|	 |虚函数地址... |
|本类成员变量2      |													    |**************|
|本类成员变量...    |     __vftable
|虚表指针          | -----> 虚函数表   |**************|
|虚基类成员变量1    |					| 虚函数地址1   |
|虚基类成员变量2    |					| 虚函数地址2   |
|虚基类成员变量...  |				    | 虚函数地址... |
|*****************|					|**************|

image-20211223203251089

image-20211223203407505

image-20211223203638039

image-20211223203818140

3.菱形继承                                       
|********************************|               |******************************|  
|第一个继承的父类的偏移块地址         | -----> 偏移块  |偏移块地址到虚表指针的距离        |
|第一个继承的父类的成员变量1         |               |偏移块地址到虚基类的偏移地址       |
|第一个继承的父类的成员变量2         |               |******************************|
|第一个继承的父类的成员变量...       | 			    
|第二个继承的父类的偏移块地址        | -----> 偏移块  |******************************| 
|第二个继承的父类的成员变量1         |			    |偏移块地址到虚表指针的距离        |
|第二个继承的父类的成员变量2         |			    |偏移块地址到虚基类的偏移地址       |
|第二个继承的父类的成员变量...       |			    |******************************|
|.............................   |
|本类的成员变量1                   |	
|本类的成员变量2                   |	
|本类的成员变量....                |	
|虚基类成员变量1                   |					 
|虚基类成员变量2                   |					 
|虚基类成员变量...                 |				     
|*******************************|					 

image-20211223204346700

4.菱形继承有虚函数
【子类自己拥有虚函数并不会增加虚表指针,而是直接在虚基类的虚表中进行了修改】
|*******************************|                 |******************************|    |**************|
|第一个继承的父类的虚函数指针        | -----> 虚函数表  |偏移块地址到虚表指针的距离         |    |虚函数地址1    |
|第一个继承的父类的偏移块地址        | -----> 偏移块    |偏移块地址到虚基类的偏移地址       |    |虚函数地址2    |
|第一个继承的父类的成员变量1        |				  |******************************|	  |虚函数地址...  |
|第一个继承的父类的成员变量2        |				                                      |**************|
|第一个继承的父类的成员变量..        |				  |******************************|	  |************ |   
|第二个继承的父类的虚函数指针       | -----> 虚函数表    |偏移块地址到虚表指针的距离        |    |虚函数地址1    |
|第二个继承的父类的偏移块地址       | -----> 偏移块      |偏移块地址到虚基类的偏移地址      |    |虚函数地址2    |
|第二个继承的父类的成员变量1        |   				  |******************************|	  |虚函数地址...  |
|第二个继承的父类的成员变量2        |   				                                      |**************|
|第二个继承的父类的成员变量...      |
|.............................  |
|本类的成员变量1                  |
|本类的成员变量2                  |
|本类的成员变量....               |				   |**************|	
|虚基类的虚函数指针                | -----> 虚函数表    |虚函数地址1    |
|虚基类成员变量1                  |				   |虚函数地址2    |
|虚基类成员变量2                  |			       |虚函数地址...  |
|虚基类成员变量...                |				   |**************|
|*******************************|

image-20211223205019303

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:17:43  更:2021-12-24 18:19:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 0:05:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码