C++函数模板与类模板实例解析(2)
与其他类一样,我们既可以在类模板内部,也可以在类模板外部定义其成员函数。定义在类模板之外的成员函数必须以关键字template开始,后接类模板参数列表。
template <typename T> return_type class_name<T>::member_name(parm-list) { }
默认情况下,对于一个实例化了的类模板,其成员函数只有在使用时才被实例化。如果一个成员函数没有被使用,则它不会被实例化。
类模板和友元
当一个类包含一个友元声明时,类与友元各自是否是模板是相互无关的。如果一个类模板包含一个非模板的友元,则友元被授权可以访问所有模板的实例。如果友元自身是模板,类可以授权给所有友元模板的实例,也可以只授权给特定实例。
// 前置声明,在将模板的一个特定实例声明为友元时要用到 template<typename T> class Pal; // 普通类 class C { friend class Pal<C>; // 用类C实例化的Pal是C的一个友元 template<typename T> friend class Pal2; //Pal2所有实例都是C的友元;无须前置声明 }; // 模板类 template<typename T> class C2 { // C2的每个实例将用相同类型实例化的Pal声明为友元,一对一关系 friend class Pal<T>; // Pal2的所有实例都是C2的每个实例的友元,不需要前置声明 template<typename X> friend class Pal2; // Pal3是普通非模板类,它是C2所有实例的友元 friend class Pal3; };
类模板的static成员
类模板可以声明static成员。类模板的每一个实例都有其自己独有的static成员对象,对于给定的类型X,所有class_name<X>类型的对象共享相同的一份static成员实例。
template<typename T> class Foo { public: void print(); //...其他操作 private: static int i; }; template<typename T> void Foo<T>::print() { cout << ++i << endl; } template<typename T> int Foo<T>::i = 10; // 初始化为10 int main() { Foo<int> f1; Foo<int> f2; Foo<float> f3; f1.print(); // 输出11 f2.print(); // 输出12 f3.print(); // 输出11 return 0; }
我们可以通过类类型对象来访问一个类模板的static对象,也可以使用作用域运算符(::)直接访问静态成员。类似模板类的其他成员函数,一个static成员函数也只有在使用时才会实例化。
- 上一篇:C++ 多重继承和虚拟继承对象模型、效率分析
- 下一篇:C++多重继承与虚继承分析