这几天翻出了很久前看过的Inside the C++ Object Model,发现很多东西忘记了,这一遍看下去,想把主要的几个对象模型记下来,也算是把书读薄吧。
1. 简单对象模型(没有虚函数,继承)
例子:
class Point {
public:
Point(float xval, float yval);
float x() const;
float y() const;
static int PointCount();
private:
float _x;
float _y;
static int _point_count;
};
对象模型:
2. 有虚函数的
例子:
class Point {
public:
Point(float xval, float yval);
virtual ~Point();
float x() const;
float y() const;
static int PointCount();
protected:
virtual ostream& print(ostream &os) const;
private:
float _x;
float _y;
static int _point_count;
};
对象模型
3.没有虚函数的继承
例子:
class Point {
public:
Point(float xval, float yval);
float x() const;
float y() const;
static int PointCount();
private:
float _x;
float _y;
char _t;
static int _point_count;
};
class Point3D {private:
float _z;
public:
Point3D(float x, float y, float z);
float z() const;
};
对象模型(假定编译器按照8字节对齐,float是4字节的)
4.含有虚函数的继承
例子:
class Point {
public:
Point(float xval, float yval);
virtual ~Point();
float x() const;
float y() const;
static int PointCount();
protected:
virtual ostream& print(ostream &os) const;
private:
float _x;
float _y;
static int _point_count;
};
class Point3D {private:
float _z;
public:
Point3D(float x, float y, float z);
float z() const;
};
对象模型是:
-------------------------------------------------------------------华丽的分割线--------------------------------------------------------------------
* 以上都是假设vptr是在对象地址头部,不同编译器实现不一样,一般有在头部和尾部的不同。
* 另外虚函数在vtbl的索引一般是第0项是type info,第1项是虚析构函数。vc的实现基本是这样,只不过vptr直接指向第一项了。
5. 带虚函数的多重继承
例子:
class Base1 {
public:
Base1();
virtual ~Base1();
virutal Base1 *Clone() const;
protected:
float _base1_data;
};
class Base2 {
public:
Base2();
virtual ~Base2();
virtual Base2 *Clone() const;
protected:
float _base2_data;
};
class Derived: public Base1, public Base2 {
public:
Derived();
virtual ~Derived();
virtual Derived *Clone() const;
protected:
float _derived_data;
}
对象模型:
*当使用指向第二个base subobject的指针调用Clone函数的时候,指针必须被调整到执行Derived对象起始地址,而使用指向第一个base subobject的指针去掉用则不会存在这个问题,有一些编译器针对这个问题,做了一些优化,虚函数被包装成一个特殊处理函数放到的的vtbl中,特殊处理一开始先调整this指针,然后才执行真正的代码逻辑。这种优化技术称为thunks,具体描述见http://en.wikipedia.org/wiki/Thunk_(object-oriented_programming)
概述:
总的来说,C++对象模型是兼容C的,为了支持多态,又引入了虚函数机制,而所谓的虚函数机制,只是编译器在c语言基础上默默加上了vptr和vtbl,并对用户透明的维护这些值。了解了这些原理,完全可以在纯C的环境模拟编译器干的这些事情。
TODO:虚拟继承的对象模型