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

1、Template是STL的基础。

2、当定义一个指针指向特定的实例时,程序中并没有发生什么,因为指针不是对象,编译器不需要知道该类的任何成员数据或对象的分布。现在编译器已经禁止声明一个指向某个模板类的指针。

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

4、当实例化一个类时,实例出来的对象空间大小必须能够容纳其非静态成员数据,成员函数并不会被实例化,只有在成员函数真正被使用时,才会被实例化出来。

5、成员函数的实例化,目前编译器并不遵循这项要求,之所以由使用者来主导实例化,有两个原因:

    (1)空间和效率的考虑。模板中大量的函数不被使用那么会造成巨大的浪费。

    (2)尚未实现的机能。并不是一个template实例化的所有类型就一定能完整的支持一组成员函数所需要的运算符。

6、在int 和long一致的架构中,使用它们将模板类实例化会产生两种实例。

7、使用模板应该注意的地方:因为模板类型不确定,所以对一个模板类型的变量赋初值可能会是错误的。因为模板类型不确定,所以并不是所有运算符都会支持。模板最后应该以分号结束。因为,在模板类中,所有关于类型的检查会延迟到实例化之后才会发生。

8、编译器在处理模板类声明时,可能有一些错误会被编译器标示出来,但是这个编译器的处理策略有关。

9、目前的编译器,面对一个模板声明,在它被一组实参实例化之前,只能施行有效的错误检查。

10、模板的定义端和实例化端也就是声明定义和实例化作用域的问题。模板中对于一个非成员名决议的结果是根据这个name的使用是否与用以实例化该模板的参数类型有关而决定,如果其使用互不相关,那么就以声明定义的作用来确定name,如果相关那么就以实例化作用域来决定name。

11、这就意味着,一个编译器要保持两个scope contexts,其实也就是模板一般化和模板特化,一个用以一般的模板类,另一个用以专注于特定的实例。

12、如果一个虚函数被实例化,其实例化点紧跟在其class实例化点之后。

13、异常处理:如果要支持异常处理,编译器的主要工作就是找出catch语句,用来处理被抛出来的exception。

14、C++的异常处理由三个主要词汇组件构成:

    (1)一个throw子句,它在程序某处发出一个exception,被抛出去的exception可以是内建类型,也可以是使用者自定类型。

    (2)一个或多个catch子句,每一个catch子句都是exception handler,这个字句准备处理某种类型的exception,并且在封闭的大括号区段中提供实际的处理程序。

    (3)一个try区段,它被围绕以一系列的叙述句,这些叙述句可能会引发catch子句起作用。

15、对异常处理的支持,当一个异常未发生时,编译系统要完成以下事情:

    (1)检验发生throw操作函数。

    (2)决定throw操作是否发生在try区段中。

    (3)若是,编译系统必须把exception type拿来和每一个catch子句进行比较。

    (4)如果比较后温和,流控制交到catch子句中。

    (5)如果throw的发生不再try子句或没有一个catch子句温和,那么系统必须摧毁所有活动的局部对象,从堆栈中将目前的函数unwind掉,进行到程序堆栈的下一个函数中。然后重复上述2-5阶段。

16、C++缺乏一个保证安全的向下转换,只有类型真的可以被适当转换时,你才可以执行向下转换。

17、dynamic_cats运算符可以在执行期决定真正的类型。

18、程序执行中对一个类指针执行dynamic_cast运算符会得到true或false:如果传回真正的地址则表示这一对象的动态类型被确定了,一些与类型有关的操作现在可以施行其上。如果传回0,则表示没有指向任何对象,意味着应该以另一种逻辑施行于这个动态类型未确定的对象身上。

19、如果dynamic_cast施行于引用身上,不会像上面那样,如果引用为0,会产生一个临时对象,临时对象的初值为0,会发生下面的事:如果引用真的参考到适当派生类,向下转换会被执行而程序可以继续进行。如果引用并不是一种派生类,由于不能传回0,所以跑出一个异常。

20、typeid运算符,主要用于判断两个对象是否是同一个类。返回值为type_info。

posted @ 2019-06-04 11:16  吾之求索  阅读(204)  评论(0)    收藏  举报