主要探讨的有三个问题:template、异常处理、执行期类型识别
A. Template
定义一个template(模板定义域)
Template<class T>
Class point{
Public:
Enumstatus{a,b};
Point(Ta=0,T b=0);
~point();
Void*operator new(size_t);
Void operator delete(void*,size_t);
Private:
Staticpoint<T> *freeList;
Int_val;
Ta,b;
};
模板实例化域。
Point<float> str;
1. 必须清楚的是template与具体的类型有关系,所以在真正的类型被指定之前,不会有什么动作,包括类中的静态成员。
2. 当编译器看到template class定义的时候,什么都不会做。所以在实际程序中什么都没有,status,freeList都不能用,必须绑定类型才能用。
3. 像point <float> *p=0,因为只是产生一个指针,本身并不是一个point,所以也不会做什么。
但是引用则不一样,必须与一个存在的对象关联,所以point<float> &ref=0,则会扩展临时对象,0被转化为point。所以是有对象产生的。
4. 对于错误诊断,编译器对template是完全解析但不做类型检验。因为类型没有被指定,所以不知道那些操作是对的哪些操作是不允许的。
5. Template 中的名称决议法:对于template中类型不会变动的成员,如已经指定 int _val,_val的类型不会变动,所以对_val的使用与T无关,所以使用模板定义域来决定。而如果相关 如 a,b,则使用模板实例化域来决定。
B. 异常处理
1. C++的exceptionhandling由三个主要词汇组件组成。Throw,catch,Try(可能会引发catch语句起作用)。
2. 对exception发生时,编译系统要完成以下事情:
i.检验发生throw操作的函数(throw可能显式给出,也可能隐式呀)
ii.决定throw操作是否发生在try区段中
iii.如果是,编译系统必须把exception type拿来和每一个catch子句进行比较。
iv.如果比较吻合,则流程控制应该交给catch语句
v.如果throw没有发生在try区段或者没有catch语句匹配,那么系统必须要:摧毁所以active local object、从堆栈中将目前的函数推出、进行程序堆栈中的下一个函数中去。
3. 如果一个exception被基类匹配,进行catch处理。
如果catch处理的参数不是引用,那么将会使用复制构造函数,非基类部分将会被截掉。如果涉及到了virtualfunction,在vptr将会被置为基类的virtual table,不会拷贝exception的vptr。当该exception再次被抛出的时候,还是原来的exception。
如果catch处理的参数是引用,那么什么操作都是在原exception上操作,没有重新拷贝,所以再次抛出的时候,是被修改后的exception。
C. 执行期类型识别
1. Dynamic_cast运算符可以在执行期间决定真正的类型。如果成功则传回被适当转换过的指针。
Dynamic_cast的成本是,类型需要一个类型描述器,被编译器产生出来。而类型描述器必须在执行期通过vptr获得。。。。。所以dynamic_cast是被多态类适用的。
在使用dynamic_cast可以将子类指针转为基类指针,使用基类指针调用子类实现的函数,实现了多态。。。这个简单的功能,我认为和直接将子类指针赋值给基类指针一 样。
2. 类型描述器的地址,就是虚表中的第一个slot中的部分内容,type_info,其中必须要含有的内容为class的真实名称和在type_info 之间的排序算法。
3. Typeid运算符传回一个constreference,类型为type_info(他是一个类)。
4. 虽然RTTI只适合用于多态类,type_info也适用于内建类型,以及非多态的使用者自定义类型。而内置类型的type_info的获得一般是静态获得的,并且在需要的时候获得。。