布局负担C++ 对象模式
简单对象模型表格驱动对象模型C++对象模型虚函数和虚函数表 C++如何支持多态类对象占用内存计算多态下对象占用内存情况
ZooAnimal 和 Bear 关系1ZooAinmal 和 Bear 关系2ZooAnimal, Bear 和 Panda 关系3
关于对象
布局负担virtual function 机制 用以支持一个有效率的“执行期绑定”(runtime binding)virtual base class 用以实现“多次出现在继承体系中的base class, 有一个单一而被共享的实体” C++ 对象模式
//Point class definination 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 tablevptr (virtual table ptr)
每一个class object被添加了一个指针,指向相关的virtual table。 通常这个指针被称为ivptr. vptr的设定(setting)和 重置(resetting) 都由每一个class 的 构造,析构,拷贝运算符自动完成。type_info
每一个class 所关联的type_info object也;经由virtual table被指出来
C++如何支持多态
1.经过隐式的转化 *** 作, 例如将一个派生类指针转化成一个指向基类的指针
// example 1 shape *ps = new circle();
2.经由virtual function的机制
ps->rotate( )
3.经由dynamic_cast 和 typeid运算符
if ( circle *pc = dynamic_cast类对象占用内存计算(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_castZooAinmal 和 Bear 关系2(pz)) { pb2->cell_block; }
Bear b; ZoomAnimal za = b; //调用ZooAnimal:: rotate() 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 za; ZooAnimal *pza; Bear b; Panda *pp = new Panda; pza = &b; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)