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)是不依赖于模板参数的名字,以及模板本身的名字和其内部声明的名字(成员、友元,本地变量),其在模板定义时解析。
参考