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继承的类抽离为同一个。

还需要了解的问题:

  1. c++中的name mangle的规则
posted @   bug批发零售  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示