c++的对象模型(简要)
c++虚函数表位于.rodata段,虚函数位于代码段。
当基类有虚函数时
1.每个类都有虚指针和虚表
2.如果不是虚继承,那么子类将父亲的虚指针继承下来,并指向自己的虚表(发生在对象构造的时候),有多少个虚函数,虚表里面的项就会有多少,多重继承时,可能存在多个基类虚表和虚指针
3.如果是虚继承,那么子类会有两份虚指针,一份指向自己的虚表,另外一份指向虚基表。多重继承时候虚基类表和虚基类表指针有且只有一个
常见的对象模型
在cpp中数据成员有静态和非静态两种,,成员函数有静态,非静态和虚函数三种。
简单对象模型
opject是一系类的slot每个slot指向了一个成员,所有成员按照声明的顺序排列,各被指定了一个slot,没有被采用。
表格驱动对象模型
cpp的成员含有数据成员和成员函数两种,表格驱动模型就是由此划分的,在这个模型中object内涵两个表格的指针,函数表是一系列的slot,每一个slot指向一个成员函数。数据成员表则直接持有data本身
cpp对象模型
在此模型中对数据成员的处理如下:
- nostatic 成员被放置在class object中
- static 成员函数被放置在class object之外
成员函数的处理如下
- 普通函数存放在class object之外
- virtual 函数:对class每个virtual函数产生一个指针,存放在virtual table中,然后在class中安放一个指针,指向上面的virtable,这个指针称为vptr,vptr的设定和重置,都由每个类的构造函数和析构函数来完成。
内存的布局
在虚拟内存中分为 .text段 .rodata段 data段 bss段 heap段 sharedmemory段 stack段 内核区
一个对象如果是在stack中初始化的那么
- 他的虚指针在class的最头部,后面是nostatic数据(内存要补齐)
- 虚函数表在rodata区域,可以通过 (longlong)(longlong*)&class来寻找虚函数表的第一项。
- 所有的函数(包括虚函数)都存放在代码区 (func)(longlong)((longlong)&class)来查看第一个虚函数指令的地址。