原文:
https://www.cnblogs.com/HelloGreen/p/12641645.html
简单对象模型:
为所有成员建立一个Slot,也就是一个指针,让这个指针指向数据
在简单对象模型下,因为类的函数成员,数据成员都没有直接放到对象模型中(放入的是指向成员的指针),因此可以解决“因menbers不同因而需要不同的存储空间”(没明白书上这句话的意思)的问题。
优点:简单
缺点:
每增加一个成员,对象模型就得增加一个指针,内存与成员数量成线性关系
每次访问member,都需要通过slot索引
表格驱动对象模型:
将对象成员分成两类,数据成员,函数成员,并将它们分别放在数据成员表,函数成员表中。
然后生成两个分别指向数据成员表,函数成员表的指针。
优点:
缩小了对象模型内存,解决了简单对象模型内存与成员线性关系的问题
在对象的非静态成员数据改变,其余不变时不需要重新编译
缺点:
难以支持多态
由于有表格的存在,因此每次查找成员时多了一次寻址,以确定在表格中具体的位置
C++对象模型:
为虚函数建立虚表,并由虚表指针指向虚表,通过虚表确认具体调用的虚函数
每一个class所关联的type_info oject也由virtual table被指出(用来支持 运行时类型识别),通常放在虚表的第一个位置。
非静态成员数据保存在对象模型中
非虚成员函数和全局函数类型,放在代码区,不存储在对象模型中
优点:
查找数据通过基地址+偏移量查找
支持多态
对于非虚成员函数,直接根据地址就可以调用,相对于表格驱动对象模型不必要多寻址一次。
- 虚函数调用
- 这也是面试中的高频考点通过实际的对象指针(即this指针),查找虚表,调用虚表中对应的函数。编译时所作工作
- 将父类的虚函数和子类的虚函数进行逻辑判断,确定子类的虚函数表中存放的虚函数,是父类的虚函数实现,还是子类的虚函数实现
- 运行时所作工作:
- 子类对象实际调用虚函数时,在运行时查找虚函数表,才知道调用的是哪个函数(是父类的,还是子类的)普通成员函数调用和全局函数调用类似注意:成员函数名必定不会冲突。
- 因为普通成员函数的第一个参数是this指针,即使不同的类,普通成员函数名相同,函数参数也不同。