分享
 
 
 

深入探讨C++对象模型 之 站在对象模型的尖端

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Template:

Template 的二个问题:

1. template 的声明。当编译器看到一个template 声明时,编译器什么反应都没有。一切都不可用,只有通过template 的某个实体来存取或操作。

2. template 的具现。

Point < float > fPoint;//产生一份实体与Point class 的float instantiation 在程序中产生关联。

Point < float > *ptr = 0;//程序什么也没有发生,因为一个指向class object 的指针,本身不是一个class object。不需要具现一个float 实体。

Point < float > &ref = 0;//会具现出一个“Point 的float 实体”,他的真正语意是:

Point < float > temporary ( float ( 0 ) );

Const Point < float > &ref = temporary;

因为reference 并不是无物的代名词。0被视为整数,必须被转换为类型为Point < float > 的一个对象。如果没有转换的可能,这个定义就是错误的,会在编译时被挑出来。

C++ Standard 让使用者来主导“具现”规则,有两个主要原因:

空间和时间效率的考虑。Member functions 的具现时间有使用者决定。

尚未实现的机能。有些用到的运算符可能一些具现的实体没有定义,由使用者来主导“具现”规则,template 就能够支持那些本来可能造成编译时期错误的类型。

Template 机制使类型检验被拖到“具现”操作发生时才进行,因而导致很多十分漏骨的错误声明都能通过编译。

Template 之中,对于一个nonmember name 的决议结果是根据这个name 的使用是否与“用以具现出该template 的参数类型”有关而决定的。如果其使用互不相关,那么就以“定义出template 的程序”来决定name。如果其使用互有关联,那么就以“具现出template 的程序”来决定name。

这意味着一个编译器必须保持两个scope contexts:scope of the template declaration;scope of the template instantiation.

Member Function 的具现行为:

Member functions 可能在编译时期或链接时期被具现出来。

编译器必须回答三个问题:

编译器如何找出函数的定义?

Ø 方法一:包含template program text file,就好象它是个header 文件一样。

Ø 方法二:要求一个文件命名规则:在.h文件中发现的函数声明,必须在.c 或.cpp中找到template program text。

编译器如何能够只具现出程序中用到的member functions?

Ø 方法一:把所有的member functions 都产生出来。

Ø 方法二:仿真链接操作,检测看看哪一个函数真正需要,然后只为它(们)产生实体。

编译器如何阻止 member definitions 在多个.o 文件中都被具现呢?

Ø 方法一:产生多个实体,然后从链接器中提供支持,只留下其中一个实体,其余都忽略。

Ø 方法二:由使用者来导引“仿真链接阶段”的具现策略,决定哪些实体才是所需求的。

Template 机制的各种实现的弱点就是当实体第一次被产生出来时或是被非必要的再次具现或是“决定那些函数是否需要具现”所花的代价太大是,会大量增加编译时间,编译器的表现另人失望。

C++语言规定:如果一个virtual function 被具现出来,其具现点紧跟在其class 的具现点之后。

C++ Standard 已经扩充了对template 的支持,允许程序员明确地要求在一个文件中将整个class template 具现出来

Template class Point3d < float >;

或是针对一个template class 的个别member function:

template float Point3d < float >::x() const;

或是针对某个个别template function:

template Point3d < float > operator+( const Point3d < float >&, const Point3d < float >& );

异常处理

Exception Handling 包括三部分:

1. 一个throw 子句。它在程序某处发出一个exception。被丢出去的exception 可以是内建类型,也可以是使用者自定类型。

2. 一个或多个catcha 子句。每一个catch 子句都是一个exception handler。它用来表示说,这个子句准备处理某种类型的exception,并且在封闭的大括号区段中提供时间的处理程序。

3. 一个try 区段。它被围绕以一系列的叙述句。这些叙述句可能会引发catch 子句起作用。

当一个exception 被丢出去时,控制权会从函数调用中被释放出来,并寻找一个吻合的catch 子句。如果都没有吻合者,那么默认的处理例程terminate() 会被调用。

当一个exception 发生时,编译系统必须完成以下事情:

1. 检验发生throw 操作的函数;

2. 决定throw 操作是否发生在try 区段中;

3. 若是,编译系统必须把exception type 拿来和每一个catch 子句比较;

4. 如果比较吻合,流程控制应该交到catch 子句手中;

5. 如果throw 的发生并不在try 区段中,或没有一个catch 子句吻合,那么系统必须(a)摧毁所有active local objects,(b)从堆栈中将当前的函数“unwind”掉,(c)进行到程序堆栈中的下一个函数中去,然后重复上述步骤2~5。

执行期类型识别

C++ 的RTTI 机制提供了一个安全的downcast 设备,但是只对那些展现“多态”的类型有效。但是怎么分辨一个class 是否具有“多态”性质呢?在C++ 中,一个具备多态性质的class,正是内含着继承而来的virtual functions。因此可以把与该class 相关的RTTI object 地址放进virtual table 中(通常放在第一个slot中)。

Type-safe Dynamic Cast(保证安全的动态转型):

Typedef type *ptype;

Typedef fct *pfct;

Simplify_conv_op (ptype pt)

{

if (pfct pf = dynamic_cast < pfct > ( pt ) ) {

// …process pf

}

else {…}

}

dynamic_cast 的真正成本是:pfct 的一个类型描述器会被编译器产生出来。由pt 指向之class object 类型描述器必须在执行期通过vptr取得。下面是可能的转换:

( ( type_info* ) ( pt->vptr [ 0 ] ) ) -> _type_descriptor;

type_info 是C++ Standard 所定义的类型描述器的class 名称,该class 中放置着待索求的类型信息。

对一个class指针类型施以dynamic_cast 运算符,会获得true 或 false:

n 如果传回真正的地址,表示这个object 的动态类型被确认了,一些与类型有关的操作现在可以施行于其上。

n 如果传会0,表示没有指向任何object,意味应该以另一种逻辑施行于这个动态类型未确定的object 身上。

对一个class 引用类型施以dynamic_cast 运算符,会获得true 或 bad_cast exception.

n 如果reference 真正参考到适当的derived class (包括下一层或下下一层或…),downcast 会被执行而程序可以继续进行。

n 如果reference 并不真正是某一种 derived class,那么,由于不能够传回0,遂丢出一bad_cast exception。

Typeid 运算符:

Typeid( expression )或 Typeid ( type ) 返回一个const reference,类型为tyoe_info.

Simplify_conv_op ( const type &rt )

{

if ( typeid ( rt ) = = typeid ( fct ) )

{

fct &rf = static_cast < fct& > ( rt );

//…

}

else {…}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有