(1) C++ 使用封装后 的布局成本: 每个类的数据成员都会存储在每个对象中, 而每个类的成员函数则不是存储在每个对象中。 每个非内联函数只会有一个函数实体, 而内联函数 会在你使用的地方产生一个实体。
(2)class的布局以及存储时间主要的额外负担是有virtual所引起的
1.1 C++对象模式:
类数据成员分为静态与非静态, 类成员函数分为静态 非静态以及虚函数 他们在机器中是如何表现的呢?
例子:
(1)简单对象模型:
一个对象是一系列的空间,每个空间只存储一个指针,这个指针指向一个成员,如图:
好处是:避免了成员不同类型而导致的需要不同的存储空间, 这个并没有被实际用于产品中 而是被 类成员指针 所应用
(2)表格驱动的对象模型:
一个对象只含有两个指针,一个指向类数据表,一个指向类成员函数表,这两个表又有一系列的空间来存储声明的成员,如图:
这个虽然也没被实际应用,但是成员函数表的观念被用于虚函数表
(3)C++ 对象模型:
这是从简单模型派生出来的,并对内存空间和存取时间进行了优化。在此模型中 对象只会存储非静态数据成员和一个Vptr(一个用于指向 虚函数表,由class的构造函数,析构函数以及复制运算符来自动完成 详情在第五章),静态数据成员, 与成员函数(静态与非静态)都会存储在每个对象的外面,且只有一个实体,虚函数则会被存储在虚函数表中的指针所指出来,虚函数表中还会多存储一个type_info 对象的指针(此对象适用于RTTI) 详情如图:
缺点是 如果存储在对象中的非静态数据成员被改,代码就得重新编译
加上继承后
继承分为单继承,多重继承(一个继承多个)与虚拟继承
虚拟继承:就是两个类由一个类继承出来, 但是只会产生一个基类的实体
继承的底层:每一个类对象都内含一个bptr,指向一个基类表格(存放以它为基类的类的地址)。
这种实现的缺点增加了空间与存储时间上的负担
优点是:不管基类的大小和数目怎么样,类对象上只会在固定位置上存放一个基表指针,第二个优点 不需要改变类对象本身就能改变基类表 如图:
如果又有一个类继承了基类 则只需要在基类表中加一个指针(存放派生类地址)
对象模型如何影响程序?
X为一个类
代码如下:
X foobar()
{
X xx;
X *px = new X;
xx.foo();//foo 是一个虚函数
px->foo();
delete px;
delete xx;
}
这个函数可能会被内部转换为:
只需大概了解 以后再回来重看
可以先用下图来部分解释 如图: