首页 > 编程语言 >c++对象模型学习笔记

c++对象模型学习笔记

时间:2023-10-10 20:11:40浏览次数:37  
标签:函数 virtual 继承 子类 模型 笔记 vptr c++ 父类

参照大佬的博客学习了一下c++的对象模型:
https://www.cnblogs.com/skynet/p/3343726.html
有些思考需要做下记录。

  1. 对于有虚函数表的类的对象,它的起始地址处会存储vptr指向虚函数表,在这个虚函数表的前4或8字节中,会存储一个地址值,指向RTTI类型信息
  2. 对于没有虚函数表的类的对象,也就是说没有vptr,那它的类型信息怎么被找到?
    通过chatgpt的解答弄明白了,对于没有虚函数表的类,如果要通过typeid获取它的type_info对象时,在静态编译期间就确定了它的结果,所以和是否有虚函数表就没有关系了。
  3. 对于有虚函数的类,他们都有自己独立的虚函数表,可能有1个,也可能有多个。
    a. 对于普通的单继承,类似于几代单传这样的类,它就只有1个虚函数表
    b. 对于有多个父类的子类(每个父类都有虚函数),并且是普通的继承,那它就有多个虚函数表
    c. 对于虚继承的子类,子类也会有多个虚函数表
  4. 虚继承中,如果父类中没有成员变量,那子类就没有自己的虚函数表,也就是说子类对象中不会有指向属于子类的虚函数表的指针,仅有1个子类虚函数的地址信息
比如
class X {
public:
  virtual void foo() {printf("X::foo()\n");}
};
class Y: public virtual X {};
Y y;
那这样的情况下y中只有_vptr.X

class X {
public:
  virtual void foo() {printf("X::foo()\n");}
  int m_x;
};
class Y: public virtual X {};
Y y;
那这样的情况下y中有_vptr.X, _vptr.Y
区别在于X中是否有成员变量

在上述的博客文章中,有对象的内存结构示意图,其中对RTTI类型信息指针的描述是有错误的,有继承关系时,图中把RTTI的信息写成了父类的RTTI的信息,但是实际上是子类自己的RTTI信息,不管是对多继承还是虚继承,有多少个RTTI指针,它指向的type_info对象都是当前自己实际的类型的信息。

对于继承关系中vptr的数量:

  1. 普通的单继承,只会有1个vptr,它的名称是沿用父类的名称
  2. 普通的多继承,会有多个vptr,它们的名称是沿用各自父类的名称
  3. 简单虚继承,可能有1个vptr,也可能有2个vptr,具体是1还是2需要看父类中有没有成员变量,不过必然会有父类名称的那个vptr
  4. 菱形继承时(需要对继承链上的有歧义的祖先类使用virtual继承),vptr的个数是每个子类中除了virtual继承类中的vptr外所有的vptr的个数之和,另外加上virtual继承类的vptr个数

对于virtual继承的理解,相当于为当前子类新增加了一个仅仅属于当前类的虚函数表,与原来的virutal继承的类的虚函数表区分开来,后续如有菱形继承的话就方便把对应的virutal继承的类抽离为同一个。

标签:函数,virtual,继承,子类,模型,笔记,vptr,c++,父类
From: https://www.cnblogs.com/lifewithlight/p/17755619.html

相关文章

  • npm笔记
    npmconfigsetcache"D:\nodejs\node_cache"//设置缓存文件夹npmconfigsetprefix"D:\nodejs\node_global"//设置全局模块存放路径npminstall-gcnpm--registry=https://registry.npm.taobao.orgnpminstallyarn-gyarnconfigsetglobal-folder&qu......
  • 莫比乌斯反演 学习笔记
    前置知识整除分块把之前写的博客搬过来了模型求\(\large\sum^{n}_{i=1}\lfloor{\frac{n}{i}}\rfloor\)假设\(n\)等于10,我们可以列出下表:\(\i\)12345678910\(\frac{10}{i}\)10532211111如果我们的\(n\)更大时,我们可以发现\(\fra......
  • tar命令的基础使用(笔记)
    tar命令的基础使用tar[选项][文件]基本操作exam:tar-cfarchive.tarfoobar#归档tar-tvfarchive.tar#列出归档tar-xfarchive.tar#解包选项作用-c创建-t列出归档内容-f指定文件-x从归档中解出文件-v显示更多......
  • .net8 AOT笔记
    .net8AOT笔记 近期。net8发布了第一个rc版本,刚好近期在做一些.net6下的一些程序验证,顺带试了下。以x64为例系统ubuntu22.4x64 下载.net8sdkhttps://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-8.0.100-rc.1-linux-x64-binaries 安装.net8mkdir-p......
  • C#学习笔记--逻辑语句(分支和循环)
    逻辑语句条件分支语句条件分支语句可以让顺序执行的代码逻辑产生分支,满足对应条件地执行对应代码逻辑。IF语句//IF语句块inta=5;if(a>0&&a<15)//注意结尾无分号{Console.WriteLine("a在0到15之间");}//if……else结构if(false){Console.WriteLine("满足if......
  • Vue学习笔记(八):Vue脚手架
      Vue脚手架是Vue官方提供的标准化开发工具,使用Vue脚手架(vue-cli)可以快速创建vue项目。  1安装npm¶  第一步(仅第一次执行):下载npm,npm(nodepackagemanager)是nodejs下的包管理工具,后续下载、管理vue包都得通过npm进行,下载地址如下:http......
  • abp.vnext笔记
    安装工具dotnettoolinstall-gVolo.Abp.Cli--version6.0创建项目abpnewTodoApp--version6.0.0配置数据库连接修改TodoApp.DbMigrator和TodoApp.Web项目的appsettings.json"ConnectionStrings":{//"Default":"Server=(LocalDb)\\MSSQLLocalDB;Da......
  • 《复盘:对过去的事情做思维演练》读书笔记
    复盘是对过去所作的事情进行回顾、反思和探究,找出原因,找到规律,从而指导我们解决问题,帮助我们提升。对于复盘来说,回顾、反思、探究、提升,一个都不能少。复盘的由来复盘,原本是围棋中的一个术语。当下完一盘棋之后,要重新再棋盘上走一遍,看看哪些子下的好,哪些子下得不好,哪些地方可以......
  • 学习笔记:斜率优化
    引入有时候我们会遇见一些dp式子\[f_i=\min(f_j+a_i\timesb_i)(j\leqi-1)\]这些式子和\(j\)没有任何关系可以前缀处理最小值\(O(n)\)快速解决但是有些式子是这样的\[f_i=\min(f_j+a_i\timesb_j+c_i)\]这种问题可以使用斜率优化至\(O(n\logn)\)例题传送门很......
  • C++ libwebsockets搭建WebSocket服务端及Http客户端、服务端
    https://blog.csdn.net/fantasysolo/article/details/88908948  概念WebRTCWebRTC,名称源自网页即时通信(英语:WebReal-TimeCommunication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联......