您的位置:首页 > 编程语言 > C语言/C++

【深度探索C++对象模型读书笔记】【第7章】站在对象模型的尖端

2015-06-16 16:13 411 查看
一、Template

1、class expression templates将在编译时期而非执行时期被评估,因而带来重大的效率提升。

2、当编译器看到template class声明时,在实际程序中,什么反应也没有。template class中的任何member,只能通过template class的某个实例来操作。

template <class Type>
class Point{
public:
enum Status{ unallocated,normalized };
Point(Type x=0.0,Type y=0.0,Type z=0.0);
~Point();
void* operator new(size_t);
void operator delete(void*, size_t);
private:
static Point<Type> *freeList;
static int chunkSize;
Type _x, _y, _z;
};
//我们可以这样写:
Point<float>::Status s;
//但不能这样写:
Point::Status s;


3、 如果定义一个指针,指向特定的实例,如:Point< float > *ptr = 0; 程序中什么也没有发生,因为一个指向class object的指针,本身并不是一个对象,编译器不需要知道与该class有关的任何members的数据或object的布局数据,因此将一个Point实体实现没有必要。如果不是pointer而是reference,那么它真的会实例化一个Point的float实例,因为reference并不是无物的代名词。

4、memberfunctions(至少对于那些未被使用过的)不应该被实体化,只有在member functions被使用的时候,C++ standard才要求它们被实例化。

5、所有与类型有关的检验,如果牵涉到template参数,都必须延迟到真正的实例化操作发生才得为之。

6、template之中对于一个nonmember name的决议结果,是根据这个name的使用与否与“用以实例化该template的参数类型”有关而决定的。如果其使用互不相关,那么就以“scope of the template instantiation”来决定name。如果其使用互有关联,那么就以“scope of the templatedeclaration”来决定name。

二、异常处理

1、c++的exception handling 包括三部分:

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

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

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

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

3、当一个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)。

三、执行器类型识别(Runtime Type Identification,RTTI)

1、欲支持type-safe downcast,在object控件和执行时间上都需要一些额外负担:

a) 需要额外的空间存储类型信息(type information),通常是一个指针,指向某个类型信息节点

b) 需要额外的时间以决定执行期的类型(runtime type),因为,正如其名所示,这需要在执行期才能决定

2、在c++中,一个具备多态性质的class(所谓的polymorphic class),正是内含着继承而来(或直接声明)的virtual functions。所有polymorphic classes的objects都维护了一个指针vptr,指向virtual function table,与该class相关的RTTI object地址放进virtual table中(通常放在第一个slot),那么额外的负担就降低为:每一个class object只多花费一个指针,这个指针只被设定一次,它是被编译器静态设定的,而不是在执行期有class
constructor设定(vptr才是这么设定)。

3、dynamic_cast运算符可以在执行期决定真正的类型,如果downcast是安全的(base type pointer指向一个derived type object),这个运算符会传回被适当转型过的指针,如果downcast不是安全的,这个运算符会传回0。

4、程序执行中对一个class指针类型施以dynamic_cast运算符,会获得true或false:

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

b) 如果传回0,表示没有志向任何object,意味应该以另一中逻辑施行与这个动态类型未确定的object身上

5、dynamic_cast运算符施行于一个reference时,不能够提供对指针情况下的那一组true/false,而是会发生下列事情:

a) 如果reference真正参考到适当的derivedclass,downcast会被执行而程序可以继续进行

b) 如果reference并不真正是某一种derived class,那么,由于不能够传回0,遂丢出一个bad_castexception

6、typeid运算符传回一个const reference,类型为type_info。编译器必须提供最小量信息是class的真实名称和在type_info objects之间的某些排序算法,以及某些形式的描述器,用来表现explicit class type和这一class的任何subtypes。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: