深度探索C++对象模型(简单对象模型、表格驱动模型、C++对象模型)

深度探索C++对象模型(简单对象模型、表格驱动模型、C++对象模型)

深度探索 C++ 对象模型

零、前言

对象模型是深层结构知识,关系到“与语言无关、与平台无关、跨网络可执行”软件组件的基础。

C++ 相对于精瘦的 C 来说,多了许多特性,正因如此,我们更有必要去探索、了解 C++ 对象模型,到底背着我们又发生了什么事情。在了解 C++ 对象模型之前,有必要先从简单一点的两个模型入手:简单对象模型、表格驱动模型

一、简单对象模型

现在我们考虑一个 Point 类,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
class Point {
public:
Point(float xval);
virtual ~Point();
float x() const;
static int PointCount();
protected:
virtual ostream& print(ostream& os) const;
float _x;
static int _point_count;
};

在 C++ 中,成员数据(class data member)有两种:staticnonstatic,成员函数(class member function)有三种:staticnonstaticvirtual

那么上述的 Point 类,用简单对象模型应该怎么塑模这些 data members 和 function members 呢,如下:

这个对象模型比较简单,在这个简单模型中,object 中存放的并不是 member 而是一系列的 slots,每个 slot 指向一个 member,按 member 在 class 中的声明顺序,即 object 中存放的是“指向 member 的指针”,这就避免了因不同类型的 member 需要不同存储空间所带来的问题。

二、表格驱动模型

与简单对象模型类似,但又有所不同。表格驱动对象模型将 class 中的 member 分成 data 和 function 两个部分,一个放在 data member table 中,一个放在 member function table 中,而 class object 则持有指向这两个 table 的指针。在往下划分,data member table 直接存放 data 本身,而 member function table 则是一系列的 slots,每个 slot 指向一个 member function,如下。

这种对象模型不会因 class 中 data membe 和 member function 的增减而改变其大小,但在操作 member function 时,比 data member 多了一次寻址。

三、CPlusPlus 对象模型

C++ 对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在此模型中对 data 而言 nonstatic data member 被置于class object 之内,static data member 被置于 class object 之外;对 function 而言,static 和 nonstatic member function 被置于 class object 之外,virtual member function 则由以下两步支持:

  1. 每一个 class 产生出一堆指向 virtual function 的指针,并存放于表格中,即 virtual table(vtbl);
  2. 每个 class object 被安插一个指针(vptr),指向相关的 virtual table。

上面两点是用以支持 virtual function 的。在 C++ 中,关键字 virtual 的存在只有两处,一出现在 member function 之前形成 virtual function,二出现在 inheritance 时形成 virtual inheritance(虚拟继承),若 base class 或 derived class 不是以上两种情况,也无 virtual table 之说了。

另外,在 C++ 对象模型中我们可以看到 vptr 指向的 virtual table 中多了一个 type_info,并且位于 vtbl 的第一个 slot,这是用以支持rumtime type identification(RTTI)的,vptr 这个指针的设定、重置都由每一个 class 的 constructor、destructor 和 copy assignment 运算符自动完成。

更进一步的说,pt->vtbl[0] 指向 Point 的 type_info object,pt->vtbl[1] 指向 Point::~Point(),pt->vtbl[2] 指向 Point::print()。

参考原文:
《深度探索C++对象模型》:简单对象模型、表格驱动模型、C++对象模型

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...