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()调用操作会被标示为错误。
注:自己测试结果不同 测试代码如下:
测试环境:
测试代码:
测试结果:
而如果代码修改为:
测试结果为:
不知道是不是编译器的问题,从自己测试的结果来看,函数调用是由模板的声明域来决定的。

异常处理

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

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

  1. Getting Started With Hazelcast 读书笔记(第七章)

    第七章 部署策略 Hazelcast具有适应性,能根据不同的架构和应用进行特定的部署配置,每个应用可以根据具体情况选择最优的配置: 数据与应用紧密结合的模式(重点,of就是这种) 胖客户端模式(最好用 ...

  2. Android深度探索--HAL与驱动开发----第七章读书笔记

    首先创建led驱动的设备文件,可以使用cdev_init,register_chrdev_region,cdev_add等建立主设备号的设备文件.步骤如下: 1使用cdev_init初始化cdev 2 ...

  3. 深度探索C++对象模型读书笔记-第六章执行期语意学

    在函数中,编译器会帮助将析构函数(Destructor) 安插在相应的位置.对于函数中的局部对象,会将析构函数安插在对象的每一个离开点. 例如: 1: void Function(int a) { 2 ...

  4. 《R语言实战》读书笔记 第七章--基本统计分析

    在导入数据并且将数据进行组织和初步可视化以后,需要对数据进行分布探索和两两关系分析等.主要内容有描述性统计分析.频数表和列联表.相关系数和协方差.t检验.非参数统计. 7.1描述性统计分析 7.1.1 ...

  5. 《利用python进行数据分析》读书笔记--第七章 数据规整化:清理、转换、合并、重塑(三)

    http://www.cnblogs.com/batteryhp/p/5046433.html 5.示例:usda食品数据库 下面是一个具体的例子,书中最重要的就是例子. #-*- encoding: ...

  6. #《Essential C++》读书笔记# 第七章 异常处理

    基础知识 异常处理机制有两个主要成分:异常的鉴定和发出,以及异常的处理方式.通常,不论是membe function和non-member function,都有可能产生异常以及处理异常.异常出现后, ...

  7. 深入探索C++对象模型 读书笔记

    第1章 关于对象 1.C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括: a.virtual function机制,引入vptr以及vtbl,支持一个有效率的"执行期 ...

  8. 《C#从现象到本质》读书笔记(七)第9章 泛型

    <C#从现象到本质>读书笔记(七)第9章 泛型 泛型的三大好处:类型安全,增强性能(避免装箱和拆箱),代码复用. 泛型方法是传入的参数至少有一个类型为T(尚未制定的类型,根据微软的命名规则 ...

  9. 《Linux内核设计与实现》读书笔记——第五章

    <Linux内核设计与实现>读书笔记--第五章 标签(空格分隔): 20135321余佳源 第五章 系统调用 操作系统中,内核提供了用户进程与内核进行交互的一组接口.这些接口让应用程序受限 ...

随机推荐

  1. 代理-jdk动态代理

    1.基于接口的实现,要jdk动态代理的类必须要实现一个接口: 2.中介类:实现了InvocationHandler,并重写这个接口的 方法(public Object invoke(Object pr ...

  2. Python的历史及介绍

    Python的诞生 Python的创始人吉多·范罗苏姆(Guido van Rossum),在1989年12月的圣诞节期间,为了打发时间,决定开发一种新的脚本解释程序,作为ABC语言的继承. 现在,p ...

  3. HttpClient异常处理手册

    HttpClient异常处理手册 开源中国 发表于 2014-08-26 19:44:06 异常处理 HttpClient的使用者在执行HTPP方法(GET,PUT,DELETE等),可能遇到会两种主 ...

  4. Windows下生成目录结构树

    1.进入需要生成目录结构的文件主目录 2.在当前目录打开命令行 3.输入命令 tree /f > list.txt 4.即在当前目录下生成了list.txt文件

  5. v-for 循环 绑定对象 和数组

    <!--v-for 迭代数组--> <div id="app11"> <div v-for="info in infos"> ...

  6. 【NOI2011】兔农(循环节)

    我居然没看题解瞎搞出来了? 题解: 不难想到找到每次减1的位置,然后减去它对最终答案的贡献. 假设有一个地方是\(x,1(mod~k)\) 那么减了1后就变成了\(x,0\). 然后可以推到\(x,0 ...

  7. thinkphp 图形处理

    使用Think\Image类进行图像处理功能,支持Gd库和Imagick库,包括对GIf图像处理的支持. 实例化类库 $image = new \Think\Image(); 默认使用GD库进行图像操 ...

  8. Shiro学习(20)无状态Web应用集成

    在一些环境中,可能需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时带上相应的用户名进行登录.如一些REST风格的API,如果不使用OAuth2协议, ...

  9. Shell基础(四):字符串截取及切割、字符串初值的处理、基使用Shell数组、expect预期交互、使用正则表达式

    一.字符串截取及切割 目标: 使用Shell完成各种Linux运维任务时,一旦涉及到判断.条件测试等相关操作时,往往需要对相关的命令输出进行过滤,提取出符合要求的字符串. 本案例要求熟悉字符串的常见处 ...

  10. NX二次开发-自定义添加右键菜单RegisterConfigureContextMenuCallback

    首先声明这个知识我以前不知道,是夏天的时候看到别人在唐工的QQ群里问的,唐工说西门子官方有这个例子.那个时候我因为在忙其他事情,也就没去研究那个右键菜单到底是怎么做的.关于自定义添加右键菜单Regis ...