模板杂记(一)
模板类中的友元的类外实现时,使用类的内部类声明变量时的格式:
1 template <typename T> 2 class A 3 { 4 public: 5 private: 6 class B//声明一个内部类 7 { 8 public: 9 B(void):c(10){} 10 T c; 11 friend ostream& operator<< (ostream& os,const B& b)//内部重载<<,以利于外部使用 12 { 13 return os<<b.c; 14 } 15 }; 16 template <typename T1>//内部的模板声明,不能用T,会和类外的T重复,报错 17 friend ostream& operator<< (ostream& os,const A<T1>& a);//友元函数声明中的A<T1>& 中的T1不能换做T,这好像就是一个友元函数的模板,与class A模板类无关 18 }; 19 template <typename T>//外部实现时必须为模板 20 ostream& operator<< (ostream& os,const A<T>& a) 21 { 22 typename A<T>::B b;//访问内部类时必须使用typename,告诉编译器A<T>是一个模板类 23 return os<<b; 24 // typename T::B b; 25 }
下面的代码中Y可以是一个模板类:
1 template<typename X, typename Z, 2 template<typename T> class Y> 3 class B { 4 public: 5 B (const X& i, const Z& s) : 6 m_i (i), m_s (s) {} 7 Y<X> m_i;//一个模板类声明的对象作为另一个模板类的成员变量 8 Y<Z> m_s; 9 }; 10 11
模板类的继承示意:
1 class A { 2 public: 3 A (const T& t) : m_t (t) {} 4 T m_t; 5 }; 6 template<typename T, typename Y> 7 class B : public A<T> {//注意继承时基类的格式 8 public: 9 B (const T& t, const Y& y) : 10 A<T> (t), m_y (y) {}//与普通的继承相同,构造时应该初始化基类 11 Y m_y; 12 };
下面代码中的子类模板,可以滞后于父类的构造:
1 template<typename BASE> 2 class Shape : public BASE {//继承于一个不确定的基类 3 public: //只有在子类实例化后才能确定基类,才会有这样的特例 4 void draw (void) const { 5 BASE::draw (); 6 } 7 }; 8 class Rect { 9 public: 10 void draw (void) const { 11 cout << "绘制矩形..." << endl; 12 } 13 }; 14 class Circle { 15 public: 16 void draw (void) const { 17 cout << "绘制圆形..." << endl; 18 } 19 };
所有代码的测试环境为ubuntu12.04下的g++编译器