C++对象模型 之 关于对象

C++对象模型 之 关于对象,第1张

C++对象模型 之 关于对象

文章目录

布局负担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_cast(pz))
{
	 pb2->cell_block;
}
ZooAinmal 和 Bear 关系2
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, Bear 和 Panda 关系3
{
	ZooAnimal za;
	ZooAnimal *pza;

	Bear b;
	Panda *pp = new Panda;

	pza = &b;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714214.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存