目录

C++类与模板

声明和实现

一般情况下,类模板的声明和实现在一个头文件内完成。

如果采用声明实现分离的方式,在.h文件中声明,在.hpp文件中实现,使用该类模板时include目标.hpp文件。

类模板的继承

涉及类模板的继承有多种情况,较为常见的是

  • 父类是特化的模板类,子类是普通类

    1
    
    class Derived  public Base<int> {}
    
  • 父类是普通类,子类是模板

    1
    2
    
    template <typename T>
    class Derived  public Base {}
    
  • 父类和子类都是模板

    1
    2
    
    template <typename T>
    class Derived : public Base<T> {}
    

如果父类和子类都是模板,子类在访问父类的数据成员和函数成员时,必须使用this->或者Base<T>::对目标成员进行限定,原因是编译器在编译Derived时无法确定Base类型尚且未知,所以名字解析不会检查父类范围,缺少限定符访问父类成员将报错(找不到目标成员),加上限定符后父类成员名字判定为依赖名字二阶名字查找将在类模板实例化时解析父类成员名字。

什么是二阶名字查找?

二阶名字查找(two-phase name lookup)是模板内部名字查找的过程,之所以称之为“二阶“,是因为模板内部名字分为依赖名字和非依赖名字,这两类名字在不同时期进行解析,此规则在1993或1994年引入C++标准草案,其作用是让名字解析更加可靠,但可能与年代久远的模板代码不兼容。

什么是依赖名字和非依赖名字?

依赖名字(dependent names)是依赖于模板参数并且在模板中未声明的名字,其仅在模板实例化时解析;

非依赖名字(non-dependent names)是不依赖于模板参数的名字,以及模板本身的名字和其内部声明的名字(成员、友元,本地变量),其在模板定义时解析。


参考