c++ 2-对象模型
本文最后更新于 2024年9月24日 下午
[toc]
复合 继承 复合+继承的构造和析构顺序
复合 (has a)
继承 (is a)
复合+继承
该类型的构造顺序不受初始化时指定的初始化顺序影响。
1 |
|
更复杂的类关系可以分解成上述几个简单类型进行分析。
虚指针、虚表、虚机制、多态
- 只要有 虚函数 就有 虚指针 以及 虚表
- 那么在64位系统上我们通过
(void*)*(unsigned long *)p
即可获得vptr指向的vtable的首地址。而vtable其实就是一个指针数组,按照虚函数在类中被声明的顺序排列 g++ -fdump-lang-class xxx.cpp
会生成一个文件,该文件记录类的内存模型和虚函数表- 上面这个图的虚表是简略版,其中还包括一些其他信息,如下所示:
其中,
1.橙色线框中的内容仅限于虚拟继承的情形(若无虚拟继承,则无此内容)
2.“offset to top”是指到对象起始地址的偏移值,只有多重继承的情形才有可能不为0,单继承或无继承的情形都为0。
3.“RTTI information”是一个对象指针,它用于唯一地标识该类型。
4.“virtual function pointers”也就是我们之前理解的虚函数表,其中存放着虚函数指针列表。
this指针进一步理解
通过一个对象调用一个函数,这个对象的地址就叫做this。
编译器看到符合三个条件就会进行动态绑定,三个条件分别是指针、向上转型、虚函数。下图的向上转型发生在this指针,OnFileOpen函数的this指针类型是CDocument。
dynamic binding
动态绑定就是走虚指针 虚表那条路线,运行时决定,调用什么就看指针指向的是哪个对象。静态绑定编译时就决定了调用哪个函数,地址都写死了。
无虚函数内存布局
一个类没有虚函数的时候,其实就是结构体,它的内存布局就是按照成员变量的顺序来的。
计算占用内存大小,需要注意内存对齐。
有虚函数内存布局
参照上面虚函数的那张图
多重继承 虚继承内存布局
多重继承
1 |
|
内存布局:
进一步参考
深度探索c++对象模型
侯捷c++课程
c++ 2-对象模型
https://leelewin.github.io/p/75768c137f7441b0ae570f54167d5536/