c++对象模型学习笔记
参照大佬的博客学习了一下c++的对象模型:
https://www.cnblogs.com/skynet/p/3343726.html
有些思考需要做下记录。
- 对于有虚函数表的类的对象,它的起始地址处会存储vptr指向虚函数表,在这个虚函数表的前4或8字节中,会存储一个地址值,指向RTTI类型信息
- 对于没有虚函数表的类的对象,也就是说没有vptr,那它的类型信息怎么被找到?
通过chatgpt的解答弄明白了,对于没有虚函数表的类,如果要通过typeid获取它的type_info对象时,在静态编译期间就确定了它的结果,所以和是否有虚函数表就没有关系了。 - 对于有虚函数的类,他们都有自己独立的虚函数表,可能有1个,也可能有多个。
a. 对于普通的单继承,类似于几代单传这样的类,它就只有1个虚函数表
b. 对于有多个父类的子类(每个父类都有虚函数),并且是普通的继承,那它就有多个虚函数表
c. 对于虚继承的子类,子类也会有多个虚函数表 - 虚继承中,如果父类中没有成员变量,那子类就没有自己的虚函数表,也就是说子类对象中不会有指向属于子类的虚函数表的指针,仅有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个vptr,它的名称是沿用父类的名称
- 普通的多继承,会有多个vptr,它们的名称是沿用各自父类的名称
- 简单虚继承,可能有1个vptr,也可能有2个vptr,具体是1还是2需要看父类中有没有成员变量,不过必然会有父类名称的那个vptr
- 菱形继承时(需要对继承链上的有歧义的祖先类使用virtual继承),vptr的个数是每个子类中除了virtual继承类中的vptr外所有的vptr的个数之和,另外加上virtual继承类的vptr个数
对于virtual继承的理解,相当于为当前子类新增加了一个仅仅属于当前类的虚函数表,与原来的virutal继承的类的虚函数表区分开来,后续如有菱形继承的话就方便把对应的virutal继承的类抽离为同一个。
还需要了解的问题:
- c++中的name mangle的规则
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通