大话C++之:对象内存模型

  1. 一般继承(无虚函数覆盖)

    1. 只有一个虚指针,指向一个虚表,虚函数按顺序从祖先节点开始插入到虚表上。
    2. 字段按顺序从祖先节点开始插入到对象内存上
    3. 在这里插入图片描述
    4. 在这里插入图片描述
  2. 一般继承(有虚函数覆盖)

    1. 只有一个虚指针,指向一个虚表,虚函数按顺序从祖先节点开始,先查找是否有可以覆盖的,如果有,覆盖掉,否则插到最后。
    2. 字段按顺序从祖先节点开始插入到对象内存上
    3. 在这里插入图片描述
    4. 在这里插入图片描述
  3. 多重继承(有虚函数)

    1. 根据继承的类的数量来一一创建各自内存块,如继承了A,B,C三个类,则先后创建ABC三块,每一个均有自己的虚指针及字段,子类的虚函数分别遍历三个虚指针指向的虚表查找是否产生覆盖,如果有,则覆盖,如果没有则插入到在第一个父类的虚表里
    2. 每个类的字段按顺序跟在各个类内存块的虚指针后面。
    3. 在这里插入图片描述
    4. 在这里插入图片描述
  4. 重复继承(钻石模型)

    1. 此类型与多重继承类似,先把最底层的子类所继承的若干个间接父类(如B1, B2)当作一个整体,把它们先按单一继承创建,再根据多重继承的性质创建。

    2. 在这里插入图片描述

    3. 在这里插入图片描述

  5. 钻石型多重虚拟继承

    1. 	class B {……};
      	class B1 : virtual public B{……};
      	class B2 : virtual public B{……};
      	class D : public B1, public B2{ …… };
      
    2. 虚拟继承的就是为了解决重复继承中多个间接父类的问题。大体思想是:先从间接父类开始创建,把顶层的超类放在内存模型的最后,同时间接父类的虚表只能含有本身的虚函数(同时不能包含顶层超类的虚函数)和子类的虚函数。
    3. 间接父类每一个虚指针后紧一个vbptr虚基类表指针,变量指向一个全类共享的偏移量表,表中项目记录了对于该类而言,“虚基类表指针”与虚基类之间的偏移量。
    4. 内存模型创建过程:
      1. 先创建间接父类B1, 虚继承先创建虚指针,紧跟vbptr,接着是成员变量;遍历B1的虚函数,检查B类中是否有,如果有,则跳过;如果没有,则插入到函数表里。此时B1内存块为:vptr, vbptr, ib1, cb1; 虚函数表有:B1::f1, B1::Bf1;
      2. 重复上面步骤继续创建B2,此时内存块为:vptr, vbptr, ib1, cb1, vptr, vbptr, ib2, cb2; B2虚函数表有:B2::f2, B2::Bf2;
      3. 创建完间接父类,继而创建子类。把子类的字段按顺序紧放在内存后面,子类的函数在间接父类中接按顺序查找是否产生覆盖(同时不能包含顶层超类的虚函数),如果有,则覆盖,继续下一个函数。例如先遍历D::f,由于顶层超类包含了,跳过不处理;对于D::f1,在B1的虚函数表里找到了,则覆盖,此时B1的虚函数表为:D::f1, B1::Bf1。对于D::f2,覆盖了B2的B::f2,B2虚函数表有:D::f2, B2::Bf2; 对于D::Df,没有找到覆盖的,则插到第一个间接父类的虚函数表里。此时B1的虚函数表为:D::f1, B1::Bf1,D::Df。
      4. 最后创建顶层超类。按常规创建B类,创建完之后,用D类的虚函数遍历检查是否产生覆盖,如果有,则覆盖,否则跳过。
    5. 在这里插入图片描述
    6. 在这里插入图片描述

    参考内容:
    钻石型继承模型的内存分布
    C++ 对象的内存布局

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/428899.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式中volatile关键字的使用方法

Hi,大家好! 今天我们来学习一下volatile关键字,volatile关键字想必大家在平时编程中都见过或用过。可是小伙伴们有没有想过什么时候需要使用volatile关键字吗? 在C语言中,volatile是一个关键字,用于告诉编译器不要优化…

绘图机器 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 绘图机器的绘图笔初始位置在原点(0, 0),机器启动后其绘图笔按下面规则绘制直线: 1)尝试沿着横向坐标轴…

【Redis】RedisTemplate和StringRedisTemplate的区别

两者的关系是 StringRedisTemplate 继承 RedisTemplate 。 两者的数据是不共通的:也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。 RedisTemplate 看这个类的名字后缀是 Temp…

安康杯安全知识竞赛上的讲话稿

各位领导、同志们: 经过近半个月时间的准备,南五十家子镇平泉首届安康杯安全生产知识竞赛初赛在今天圆满落下帏幕,经过紧张激烈的角逐, 代表队、 代表队和 代表队分别获得本次竞赛的第一、二、三名让我们以热烈的掌声表示祝…

vue3+uniapp在微信小程序实现一个2048小游戏

一、效果展示 二、代码 <template><view class"page"><view class"top"><view class"score">得分:{{total}}</view><view class"time">用时:{{allTime}}s</view></view><view cl…

【代码随想录算法训练营Day34】860.柠檬水找零;406.根据身高重建队列;452.用最少数量的箭引爆气球

❇️Day 34 第八章 贪心算法 part04 ✴️今日任务 860.柠檬水找零406.根据身高重建队列452.用最少数量的箭引爆气球 ❇️860.柠檬水找零 本题看上好像挺难&#xff0c;其实挺简单的&#xff0c;大家先尝试自己做一做。题目链接&#xff1a;https://leetcode.cn/problems/lem…

python lambda表达式(匿名函数)

lambda 表达式 在Python中&#xff0c;匿名函数&#xff08;也称为lambda函数&#xff09;是一种简洁的方式来定义小函数&#xff0c;这些函数可以在需要的地方直接定义和使用&#xff0c;而不需要使用def关键字来定义一个具有名称的函数。 lambda 函数是一种小型、匿名的、内…

软件测试/测试开发|一文讲清楚你什么是测试用例

前言 对于一个测试工程师来说&#xff0c;测试用例的编写是一项必须掌握的能力&#xff0c;但有效的设计和熟练的编写确实一项十分复杂的技术。不仅需要掌握软件测试技术和流程&#xff0c;而且还要对整个软件不管从业务&#xff0c;还是对软件的设计&#xff0c;程序模块的结…

【Bugs】class path resource [xxx.xml] cannot be opened because it does not exist

报错&#xff1a; 关键报错信息&#xff1a; class path resource [scope.xml] cannot be opened because it does not exist完整报错信息&#xff1a; 2024-03-01 14:26:58 866 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refres…

外部存储器接口(EMIF)

外部存储器接口&#xff08;EMIF&#xff09; 该设备支持双核架构&#xff1b;为了为每个CPU子系统提供一个专用的EMIF&#xff0c;该设备支持两个EMIF模块——EMIF1和EMIF2。两个模块完全相同&#xff0c;具有相同的功能集&#xff0c;但具有不同的地址/数据大小。EMIF1在CPU…

赋能中国制造,大道云行发布智能制造分布式存储解决方案

《中国制造2025》指出&#xff0c;“制造业是国民经济的主体&#xff0c;是立国之本、兴国之器、强国之基。” 智能制造引领产业提质增效 智能制造是一种利用先进的信息技术、自动化技术和智能技术来优化和升级制造业生产过程的方法。它将人工智能、大数据、物联网、机器学习等…

代码工具APEX的入门使用(未包含安装)

第一次使用APEX是2019年&#xff0c;这个技术成名已久只是我了解的比较晚。请看Oracle ACE的网站&#xff0c;这就是用APEX做的。实际上有一次我看O记的人操作他们的办公流程&#xff0c;都是用APEX做的。 那一年&#xff0c;我用APEX做了一个CMDB的管理系统。那时候还没有流行…

Docker实战——容器

目录 Docker 容器的基本概念与操作1.使用“docker create”创建容器。这里基于Nginx的镜像创建了一个容器&#xff0c;名字为mycontainer。2.使用“docker ps -a”命令查看所有的容器&#xff0c;这时的容器不一定是运行状态。3.使用 “docker start” 命令可以启动容器。4.使用…

如何创建测试计划?这些要考虑到

以下为作者观点&#xff1a; 创建一个彻底和有效的测试计划对软件测试的成功至关重要。它可以帮助识别过程中可能出现的潜在问题或问题。 什么是测试计划&#xff1f; 测试计划是一份文件&#xff0c;概述了软件测试过程的策略、目标、资源和时间表。测试计划通常包括一些细…

抖店0元入驻不交钱会怎么样?个人店和个体店的利弊分析,开店必看

我是王路飞。 现在的抖店是可以开通个人店的。 也就是不需要营业执照、直接使用个人身份证就可以在抖音开店&#xff0c;而且也不需要缴纳店铺保证金就能开店运营了。 但真实情况是怎么样的呢&#xff1f;新手0元入驻抖店不交这个保证金会怎么样呢&#xff1f; 今天给想在抖…

倒计时35天

小红的子序列权值和 (nowcoder.com) #include<bits/stdc.h> using namespace std; #define int long long const int N2e56; const int inf0x3f3f3f3f; const double piacos(-1.0); const int mod1e97; int c[1100][1100]; int a[1100],b[5]; void solve() {int n;cin>…

布隆过滤器到底是什么东西?它有什么用

一、问题解析 昨天&#xff0c;一个工作了 6 年的粉丝私聊我&#xff0c;说最近面试被问到布隆过滤器没回答出来。然后在网上找了一堆资料也没有说清楚&#xff0c;想让我帮他讲解一下&#xff0c;今天正好有空&#xff0c;给大家分享一下布隆过滤器。 在解释布隆过滤器之前&a…

openGauss学习笔记-235 openGauss性能调优-系统调优-资源负载管理-资源管理准备-创建资源池

文章目录 openGauss学习笔记-235 openGauss性能调优-系统调优-资源负载管理-资源管理准备-创建资源池235.1 背景信息235.2 前提条件235.3 操作过程235.3.1 创建资源池235.3.2 管理资源池235.3.3 删除资源池 235.4 查看资源池的信息 openGauss学习笔记-235 openGauss性能调优-系…

加密与安全_ 凯撒密码

文章目录 Pre概述Code 实现 凯撒密码字母频率分析攻击Code解密凯撒密码 小结 Pre PKI - 02 对称与非对称密钥算法 概述 凯撒密码是一种简单的替换加密技术&#xff0c;也称为移位密码。它是古典密码学中最早的密码之一&#xff0c;得名于古罗马军队领袖凯撒尤利乌斯&#xff…

express+mysql+vue,从零搭建一个商城管理系统7--token

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、安装jsonwebtoken二、新建config/jwt.js三、修改models/user.js四、修改routes下的user.js五、修改index.js六、Api新建user/queryUserList接口七、token验证失败示例总结 前言 需求&#xff1a;主要学习…