前言
终于到最后一章啦,准备迎接新的篇章,刚好“霹雳布袋戏”要出新的剧集了,期待ing。
这章也是一些零散的知识点。
1. 模版的名称决议
直接上代码:
//scope of the template definition
extern double foo(double);
template < class type >
class ScopeRules{
public:
void invariant(){
_member = foo( _val );
}
type type_dependent(){
return foo( _member );
}
private:
int _val;
type _member;
}
//scope of the template instantiation
extern int foo(int);
ScopeRules<int> sr0;
sr0.invariant();
sr0.type_dependent();
这里有两个foo,两个方法调用里的foo分别对应哪个?
注意两点就ok了:
1.模版,并不是实例化的时候,就把所有的方法都实例化。
比如说这个模版里有1000个方法,都是与模版类type
相关的,而实例化模版后只用到其中的几个,那如果在实例化的时候就把1000个方法都实例化那岂不是白白做了许多无用功?所以,有些编译器会有个策略,就是只实例化需要用到的方法或者成员,其它不实例化。
回到开头的代码上,如果不调用sr0.type_dependent();
那么实例化这个方法并没什么卵用。
2.模版里用到的函数调用符号决议规则:如果这个函数调用符号与模版类型type
没半毛钱关系,那这个函数调用符号就是在模版定义的地方找相应的符号;如果这个函数调用符号与模版类型type
有关联,那么这个函数调用符号应该在实例化模版的地方找相应的符号。
所以,invariant()
里的foo应该找模版定义的地方里的foo; 而 type_dependent()
里的foo应该在它实例化的时候找相应的foo。
2. 显式模版实例化
显式要求在一个文件中将整个class template实例化
template class Point3d;
针对一个template class 个别member function:
template float Point3d::X() const;
3. 抛出Exception时保证的语意
c++的实现中,正常执行时,在每一个函数被推离堆栈之前,函数的 local class objects 的 destructor会被调用。
如果exception抛出时,exception之前的local object 会析构,后面的代码不执行!
所以才需要那些什么auto_ptr
什么的包装一层,也就是在前面声明一些auto_ptr
,即使遇到exception,auto_ptr
的析构函数也会被调用。
4. try catch 的实现原理
把函数体分为三种区域,用一个表格来标识,用类似eip(指令的位置来判断)
try区域外,没有active local object
try区域外,有active local object
try区域内
所以实现Exception handler时,就可以根据这些区域,找出有哪些local objects 。当Exception抛出时,也就知道哪些local objects需要调用析构函数。
5. Exception 必须包含所有base class的类型信息
c++ 的 RTTI(Run time type identification)执行期类型识别,有的编译器是在virtual table里的一个指针指向具体的 type_info结构来实现的。
假如产生一个exVetex异常(exVetex继承自exPoint),下面两种写法有些不同:
//1.
catch(exPoint p){
throw; //继续抛出的是exVetex,p是一个临时对象
}
//2.
catch(exPoint &p){
throw;//继续抛出的是裁剪后的exPoint
}
只有在一个catch子句评估完毕并且知道它不会再抛出exception之后,真正的exception object才会被销毁。
6. static_cast 与 dynamic_cast
static_cast 静态强制转换,不管什么类型,直接转,不安全
dynamic_cast执行期转换,对于指针,成功返回地址,失败返回0。
对于reference,成功接着执行,失败抛出bad_cast异常。抛出异常而不是用0表示失败的原因:
引用不能用0,引用0的话是产生一个临时对象,所以不能用0代表引用无物,所以抛出异常。所以需要用dynamic_cast的话需要try catch …
感觉try catch+dynamic_cast 蛋疼的话,还可以这样:
if(typeid(..) == typeid(…)){
..static_cast<>...
//typeid 返回的是一个typeInfo的结构
}