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

Template

模板是在编译时期而非执行时期被计算的。因此其不会带来效率的降低。

   1: const Point<float> &ref = 0;

该语句会实例化一个Point的float实例。该语句会被扩展为:

   1: Point<float> temp(float(0));
   2: const Point<float> &ref = temp;

这是因为0需要转换为对象,才能被引用.如果不能转换,该定义就是错误的.会在编译时被发现.

即一个class object的定义,不会是编译器暗中做(临时对象) 或是程序员显示的做(创建对象),都会导致template class的实例化。

C++ 彼岸准要求对于memberfunctions(成员函数),那些未使用的不应该被实例化,只有在member functions被使用的时候,才被实例化。

(但是目前的编译器并不精确遵循该要求。) 该要求主要基于以下两个原因

  1. 空间和时间效率的考虑。比如class中有100个member functions,而你的程序值针对某个类型使用了其中两个,针对另一个类型使用了五个,其他函数的实例化将会花费大量的时间和空间,而实际上是不需要的。
  2. 尚未实现的机能。并不是template实例化的所有类型都能完整支持member functions所需要的函数。如果只实例化真正用到的函数,template就可以支持那些实例化全部函数可能造成编译错误的类型。

Template中,对于一个非成员名字的决议结果,是根据这个名字的使用是否与用以实例化该template的参数类型有关而决定的。

  1. 如果与其实例化类型互不相关,那么就以“scope of the template declaration” 来决定name(就是定义template的程序)
  2. 如果与其实例化类型互有关联,那么就以“scope of the template instantiation” 来决定name(就是实例化template的程序)
   1: // scope of the template definition
   2: extern double foo(double);
   3:  
   4: templte<class type>
   5: class ScopeRules {
   6:   public:
   7:     void invariant() {
   8:       _member = foo(_val);
   9:     }
  10:     type type_dependent() {
  11:       return foo(_member);
  12:     }
  13:   private:
  14:     int _val;
  15:     type _member;
  16: };
  17:  
  18: // scope of the template instantiation
  19: extern int foo(int)
  20: // ...
  21: ScopeRules<int> sr0;
在ScopeRules template中有两个foo()调用操作。在scope of template definition中,只有一个foo()函数声明位于scope之内。而在scope of template instantiation中,两个foo()函数声明都位于scope中。
此时如果有一个函数调用操作:sr0.invariant()
根据上面的规则,该函数和用以实例化该template的参数类型无关,就以scope of the template declaration 来决定,在此scope中,只有一个foo()候选者,即foo(double)
而此时对于另一个函数操作:sr0.type_dependent()
该函数和用以实例化的template类型相关,就以scope of the template instantiation,在此scope中,有两个foo()候选者,由于_member的类型为int,所以调用foo(int)
最后,如果ScopeRules以某一个class类型实例化,而该class没有针对int或double实现出conversion运算符,那么foo()调用操作会被标示为错误。
注:自己测试结果不同 测试代码如下:
测试环境:
image
测试代码:
image
测试结果:
image
而如果代码修改为:
image
测试结果为:
image
不知道是不是编译器的问题, 从自己测试的结果来看,函数调用是由模板的声明域来决定的。

异常处理

C++异常处理的三个主要的组件:

  1. 一个throw语句。他在程序某处发出一个exception。被抛出的exception可以是内建类型,也可以是自定义类型
  2. 一个或多个catch语句,每个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子句吻合,那么系统必须
    1. 摧毁所有的active local objects(完成资源回收)
    2. 从对战中将目前的函数unwind
    3. 进行到堆栈的下一个函数中,重复上面2~5

  关于异常的机制和原理参考:http://www.cnblogs.com/lovemdx/p/3254108.html

转载于:https://www.cnblogs.com/lovemdx/p/3254113.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值