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

深度探索C++ 对象模型【第七章1】

2017-11-13 09:23 274 查看
1:template编程风格

它是标准模板库(STL)的基础
参数化技术
2:template类,定义一个指针指向特定的实例时,程序中并没有发生什么,因为指针并不是对象,编译器不需要知道与该class有关的任何成员数据或者对象的分布。所以编译器现在已经禁止了声明一个指向某个模板类的指针。

3:然而定义一个引用时,会真的实例化一个template class的实例,0也会被转化为类型的一个对象(引用不能指向无物),如果不能转换,会在编译期报错。

4:对于模板类中的数据成员,声明一个实例时:Point<float> A;

A 的空间大小必须足够容纳其非静态成员数据
成员函数并不会被实例化,只有在成员函数真正被使用时,才会被要求实例化出来
5:目前的编译器并不严格遵守4的第二条,现使用使用者来主导

时间与空间效率的考虑:模板类中的大量函数不被使用,造成浪费
并不是模板类实例化的所有类型都有着能够支持成员函数的一整套运算符,比如说自定义类型point,可能就没有加法运算符,这样涉及到该运算符的成员函数就有可能会出现问题。如果只实例化那些真正能用到的函数,就可以避免编译时期的错误
6:如果int 和long是一致的,(或是double和long double一致),那么模板类的实例化使用这个几种类型是否会产生两种实例呢?目前所有的编译器都是产生两种实例的。

7:使用模板类需要注意的地方

因为模板类的类型不确定,所以为一个类型的变量(对象)赋初值可能是错误的。type t = 10
因为模板类的类型不确定,所以并不是所有的运算符都会支持。 t != 100;
模板类也需要使用;分号作为结尾
然而,在模板类中,所有有关于类型的检查,如果牵涉到类型参数,都必须延迟到真正的实例化操作之后才会发生。

8:编译器在处理模板类声明时,可能会有一些错误被编译器标示出来,但这和编译器的处理策略有关。cfront只会做一些语汇检查和解析错误,只能进行一些有限的错误检查,与类型有关的检查到实例被定义之后才会进行,这也是当前编译器实现技术上的一个存在问题。

9:模板定义端和模板的实例化端也就是声明定义和实例化作用域的问题。

在对一个非成员名的决议结果时,如果该函数的实例化与template的类型参数无关,那就以声明定义(declaration)的作用于来确定name,如果有关,那就以实例化作用域(instantiation)来确定该name
10:模板类中函数的实例化相关机制稍有复杂,且各家编译器实现原理各不相同,不做讨论。

11:想要支持异常处理(Exception Handling),编译器的主要工作就是找到catch子句,以处理抛出来的exception(异常)。

12:EH的三个语汇组件

一个throw子句,它在程序某处发出一个exception。被抛出的exception可以是内建类型,也可以是自定义类型
一个或者多个catch子句,每一个catch子句都是一个EH,这个子句准备处理某种类型的exception,并且在封闭的大括号区段内提供实际的处理程序
一个try区段,它包含着一系列的叙述句,可能会引发catch子句起作用。
13:对EH的支持

第一步:检查所发生的throw操作函数
第二步:决定throw操作是否发生在try区段中
第三步:若是,则编译系统会将异常类型拿出来与每一个catch子句进行比较
若结果吻合,流程控制交到catch子句之中
如果throw的操作并没有发生在try区段中,或者是没有一个catch子句吻合,那么编译器必须进行以下操作
摧毁所有的local objects;从堆栈中将目前的函数“unwind”掉;进行到堆栈的下一个函数中去;重复2~5步骤
14:RTTI

typeid运算符,返回的是一个const reference,类型为type_info(用来保存类型)
指针指向0,将代表no object,但是引用指向0,将会引起一个临时性对象的产生,该临时对象会被设初值为0,这个reference将会被设置为该对象的一个别名
dynamic_cast,如果传回真正的地址,那么表示动态类型转换成功,传回0,表示应该以另一种逻辑施行于这个动态类型并未确定的对象身上

15:C++的对象模型将在其不断地发展中展现出其真正的全面适用性(效率以及弹性的平衡)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息