C++对象模型的探索(一)

C++对象模型

1、概念
	》语言中直接支持面向对象程序设计的部分
		》》一种“不变量”,类似于C++ class的完整virtual functions在编译时期就固定了,程序员后期无法在执行期间增加和取代其中的某一个
		》》虚拟调用可以快速派送(dispatch),付出的代价是执行期的弹性
	》对于各种支持的底层实现机制
2、C与C++的对比
	1、C语言程序性的procedural
		》数据和处理数据的操作分开来声明
			》》由一组“分布在各个以功能为导向的函数中”的算法所驱动,处理的是共同的外部数据
	2、C++封装
		》C++封装并没有增加成本
		》C++在布局以及存取时间增加的额外负担由virtual引起
			》》virtual function机制 
				》》》用以支持一个有效率的执行期绑定(runtime binding)
			》》virtual base class
				》》》用以实践多次出现在进程体系中的base class,有一个单一而被共享的实体
		》此外还要一些多重继承下的额外负担。

C语言

//申明一个struct Point3d
typedef struct Point3d
{
	float x;
	float y;
	float z;
} 
//打印一个Point3d,定义的函数
void Point3d_print(const Point3d *pd)
{
	printf("%f, %f, %f",pd->x, pd->y, pd->z);
}
//定义一个宏更有效率
#define Point3d_print(pd) printf("%f, %f, %f",pd->x, pd->y, pd->z);
//程序中直接完成操作
void my_foo()
{
	Point3d *pd = get_a_point();
	...
	//直接打印point
	printf("%f, %f, %f",pd->x, pd->y, pd->z);
}

C++,Point3d用独立的“抽象数据类型(abstract data type,ADT)*来实现:

class Point3d
{
publicPoint3d(float x = 0.0, float y = 0.0, float z = 0.0): _x(x), _y(y), _z(z){}
	float x(){return _x;}
	float y(){return _x;}
	float z(){return _x;}
	void x(float xval){_x = xval;}
private:
	float _x;
	float _y;
	float _z;
};
inline ostream&operator<<(ostream &os, const Point3d &pt)
{
	os << "{" << pt.x() << ","<< pt.y() << ","<< pt.z() << "}" 
};

一个双层或者三层的class体系完成

class Point
{
public:
	point(float x = 0.0) : _x(x){}
	float x() {return _x;}
	void x(float xval){_x = xval;}
protected:
	float _x;
};
class Point2d : public Point
{
public:
	Point2d(float x = 0.0, float y = 0.0):Point(x), _y(y){}
	float y(){return _y;}
	void y(float yval){_y = yval;}
protected:
	float _y;
};
class Point3d : public Point2d
{
public:
	Point3d(float x = 0.0, float y = 0.0, float z= 0.0) : Point2d(x,y), _z(z){}
	float z(){return _z;}
	void z(float zval){_z = zval;}
protected:
	float _z;
};

C++对象模式

1、简单对象模型
	》一个object是一系列的slots,每一个slot指向一个members,Members按其声明次序,各被指定一个slots,每一个data member或function member都有自己一个slot
	》应用在C++的”指向成员的指针“观念中
2、表格驱动对象模型
	》为了对所有class的所有objects都有一致的表达方式
	》所有与members相关的信息抽出来,放在一个data member table和一个member function table之中,class object本身则内涵指向这两个表格的指针,member function table是一系列的slots,每一个slot指向一个member function,data member table则直接含有data本身
3、C++对象模型
	》由简单对象模型派生,对内存空间和存取时间走了优化
	》Nonstatic data member 被配置于每一个class objects之内,static和Nonstatic  function  member也被放在所有的classobjects之外,Virture functions则以两个步骤支持
		》》每一个class产生出一堆指向virtual functions的指针,放在表格之中,这个表格被称为virtual table(vtbl)
		》》每一个class object被添加了一个指针,指向相关的virtual table,通常这个指针被称为vptr,vptr的设定(setting)和重置(resetting)都由每一个class的construcator、destructor和copy assignment运算符自动完成,每一个class所关联的type_info objects(支持runtime type identification,RTTI),也经由virtual table被指出来,通过是放在表格的第一个slot处。
	》》缺点:当应用程序代码本身未曾改变,class objects的nonstatic data members有改变(增加,修改,更改),应用程序也要重新编译。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

继承

1、单一继承
2、多重继承
	》虚拟继承:base class不管在继承串链中派生多少次,永远只会存在一个实体(subobject)
	》间接性的级数会因为继承的深度而增加
//单一继承
class library_materials{...};
class Book:public library_materials{};
class Rental_book :public book{...};
//多重继承
//早期的iostream实现方式
class iostream:
	public istream,
	public ostream{...};
//继承关系可以指定为虚拟的(virtual)
class istream : virtual public ios {...}

对象模型如何影响程序

不同的对象模型,会导致现有的程序代码必须修改以及必须加入新的程序代码
X foobar()
{
	X xx;
	X *px = new X;
	//foo()是一个virtual function
	xx.foo();
	px->foo();
	delete px;
	return xx;
}
//上面这个函数在内部可能会被转化成
//虚拟C++码
void foobar(X &_result)
{
	//构造_result
	//_result来取代local xx..
	_result.x::X();
	px = _new(sizeof(X));
	if(px != 0)
	px->x::X();
	//扩展下xx.foo()各不使用virtual机制
	//以_result取代xx
	foo($_result);
	//使用virtual机制扩展px->foo();
	(*px->vtb1[2])(px);
	//扩展delete px;
	if(px != 0)
	{
		{*pt->vtb1[1]}(px);
		_delete(px);
	}
	return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值