Effective cpp 读书笔记8

来源:互联网 发布:卡尔曼滤波器 知乎 编辑:程序博客网 时间:2024/05/23 13:58

模板与泛型编程

41.了解隐式接口和编译器多态

  1. classes和template都支持接口和多态

  2. 对classes而言接口是显式的,以函数签名为中心。多态是通过virtual函数发生于运行期

  3. 对template参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译器

  4. 这一条主要意思是,模板定义是编译器的多态性,存在隐式接口。比如你一个模板函数里面包含了模板参数的一些接口调用,这些接口本质上就是隐式接口


42.了解typename的双重意义

  1. 声明template参数时,前缀关键字class和typename可互换

  2. 请使用关键字typename标识嵌套从属类型名称;但不得在base class lists(基类列)或member initialization list(成员初值列)内以它作为base class修饰符

    • class和typename不等价的情况:修饰从属类型名称
    • template内出现的名称如果相依于某个template参数,称之为从属名称。如果从属名称在class内呈嵌套状,我们称它为嵌套从属名称。如C::const_iterator(C是模板参数)
    • C++解析从属名称,假设这个名称不是一个类型,而是一个变量或其他东西。如果需要修改这个默认,需要自从属名称前放置typename,这是class不能替代的

43.学习处理模板化基类内的名称

  1. 可在derived class template内通过“this->”指涉base class template内的成员名称,或借由一个明白写出的“base class资格修饰符”完成

    • 注意一个问题:但是用模板模式的时候,可能存在派生的模板类对模板参数类的函数的调用。此时,如果不是明确声明,编译器不会自动搜索模板参数类是否包含这个函数。而是在编译时报错(C++不进入templatized base classes 观察)
    • 当运用模板模式的时候,可能不是所有的派生类都完全符合模板类的所有接口,这个时候,需要全特化或偏特化模板
    • 阻止C++不进入templatized base classes 观察的行为失效,有三种办法
      – 在base class函数调用动作前加上“this->”
      – 使用using声明
      – 明白指出被调用函数位于base class 内(C::XXX())(这种方法不好,如果XXX是virtual函数,这样会关闭virtual的绑定行为)

44.将与参数无关的代码抽离templates

  1. Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系

  2. 因非类型模板参数而造成的代码膨胀,往往可消除,做法是以函数参数或class成员变量替换template参数

  3. 因类型参数而造成的代码膨胀,往往可降低,做法是让带有完全相同二进制表述的具现类型功效实现代码

    • 模板造成的膨胀:如果你的模板参数有300种可替代类型,将会有300个函数生成(class template的成员函数只有在被使用时才被暗中具现化,所以只有在这300个函数的每一个都被使用,才会生成300个)
    • 避免代码膨胀,就是避免重复,归纳起来就是:共性与变性分析
    • working set:对一个在“虚内存环境”下执行的继承而言,其所使用的那一组内存页
  4. 个人总结:模板会造成膨胀。非模板的参数会导致模板具现化的重复,通过实现模板基类,将非模板参数作为某函数的形参,则继承该基类的所有派生类共用同一份基类


45.运用成员函数模板接受所有兼容类型

  1. 请使用member function template生成“可接受所有兼容类型”的函数

  2. 如果你声明member template 用于“泛化copy构造”或“泛化assignment操作”,你还是需要声明正常的copy构造函数和copy assignment操作符

    • 同一个template的不同具现体之间并不存在固有关系(这里意思是如果以带有继承关系的B、D两类型分别具现化某个template,产生出来的两个具现体不带继承关系)
    • 通过构造模板函数,减少代码膨胀同时实现泛化的复制构造函数,注意,这里的泛化复制构造函数,它本意是希望进行隐式转化,所以不要使用explicit
    • 在class内声明泛化构造函数,不会阻止编译器生成自己的copy构造函数
0 0