关于对象
布局负担
- virtual function 机制 用以支持一个有效率的“执行期绑定”(runtime binding)
- virtual base class 用以实现“多次出现在继承体系中的base class, 有一个单一而被共享的实体”
C++ 对象模式
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 object之内
- 静态成员被存放在所有class object 之外
- 静态和非静态成员函数也被存于class object 之外
- Virtual functions布局
虚函数和虚函数表
- vtbl(virtual table)
每一个class 产生出一堆指向 virtual functions 的指针,放在表格之中。这个表格被称为 virtual table - vptr (virtual table ptr)
每一个class object被添加了一个指针,指向相关的virtual table。 通常这个指针被称为ivptr. vptr的设定(setting)和 重置(resetting) 都由每一个class 的 构造,析构,拷贝运算符自动完成。 - type_info
每一个class 所关联的type_info object也;经由virtual table被指出来
C++如何支持多态
- 1.经过隐式的转化操作, 例如将一个派生类指针转化成一个指向基类的指针
shape *ps = new circle();
ps->rotate( )
- 3.经由dynamic_cast 和 typeid运算符
if ( circle *pc = dynamic_cast<circle *>(ps))
类对象占用内存计算
- 需要多少内存才能变现一个class object?
- 其非静态成员变量总大小
- 对齐需要填补的空间
- 未支持virtual 而由内部产生的任何额外负担
class ZooAnimal
{
public:
ZoonAnimal();
virtual ~ZoomAnimal();
virtual void rotate();
protected:
int loc;
String name;
};
ZoonAnimal za("Zoey");
ZoonAnimal *pza = &za;
多态下对象占用内存情况
class Bear: public ZoomAnimal
{
public:
Bear();
~Bear();
//...
void rotate();
virtual void dance();
//...
protected:
enum Dances{ ... }
Dance dance_know;
int cell_block;
};
Bear b("Yogi");
Bear *pb = &b;
Bear &rb = *pb;
ZooAnimal 和 Bear 关系1
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;
- 每个都指向Bear 对象b 的第一个byte;
- 差别:pb 涵盖整个Bear obj, pz 所涵盖的地址只包含Bear 对象b中的ZoomAnimal subobject
合法的操作:
if( Bear *pb2 = dynamic_cast<Bear *>(pz))
{
pb2->cell_block;
}
ZooAinmal 和 Bear 关系2
Bear b;
ZoomAnimal za = b;
za.roate();
-
问题1:为什么rotate()调用的是ZoomAnimal实例而不是Bear实例? 答: za 并不(而且也绝不会是)一个Bear, 它是(并且只能是)一个ZooAnimal -
问题2 : 为什么za的vptr不指向Bear 的 virtual table? 答: 编译器在初始化和指定(assignment)操作(将一个class object指定给另一个class object)之间做出了判断。 编译器必须确保如果某个object含有一个或一个以上的vtprs, 那些vptrs的内容不会被base class object初始化或改变
ZooAnimal, Bear 和 Panda 关系3
{
ZooAnimal za;
ZooAnimal *pza;
Bear b;
Panda *pp = new Panda;
pza = &b;
}
|