#includeusing namespace std;template class Comparator {public:Comparator (T x, T y) :m_x (x), m_y (y) {}T max (void) const {return m_x < m_y ? m_y : m_x;}T min (void) const {return m_x < m_y ? m_x : m_y;}private:T m_x, m_y;};class Integer {public:Integer (int arg) : m_var (arg) {}friend ostream& operator<< (ostream& os, Integer const& i) {return os << i.m_var;}//自定义比较函数bool operator< (Integer const& i) const {return m_var < i.m_var;}/*bool operator> (Integer const& i) const {return m_var > i.m_var;}*/private:int m_var;};int main (void) {int a = 123, b = 456;Comparator ci (a, b);cout << ci.max () << ' ' << ci.min ()<< endl;double c = 1.3, d = 4.6;Comparator cd (c, d);cout << cd.max () << ' ' << cd.min ()<< endl;string e = "hello", f = "world";Comparator cs (e, f);cout << cs.max () << ' ' << cs.min ()<< endl;Comparator cn (a, b);cout << cn.max () << ' ' << cn.min ()<< endl;return 0;}
4.静态成员变量类模板的静态成员变量,既不是一个对象一份,也不是一个模板一份,而是在该类模板的每个实例化类中各有一份,且为该实例化类的所有对象所共享。
#includeusing namespace std;template class A {public:void foo (void) const {cout << "this: " << this<< ", &m_var: " << &m_var<< ", &s_var: " << &s_var<< endl;}private:int m_var;static int s_var;};template int A ::s_var;int main (void) {static A a, b;static A c, d;a.foo ();b.foo ();c.foo ();d.foo ();}
5.递归实例化-------------------------------------------------int a = 10;int b;b = a;---------------------------int a[5] = {1, 2, 3, 4, 5};int b[5];b = a; // 错误,数组不能只有直接赋值---------------------------struct Array { int a[5];};...Array a = {1, 2, 3, 4, 5}Array b = a;-------------------------------------------------用一个类模板的实例化类型实例化该类模板自身的实例化方式被称为类模板的递归实例化。通常用这种方法可以很方便地构建那些在空间上具有递归特性的数据结构,如:多维数组、二叉树等。注意:模板参数表的右尖括号一定不能紧挨着,期间至少要保留一个空格,以防止编译器将其误解为右移运算符。
#includeusing namespace std;template class Array {public:T& operator[] (size_t i) {return m_a[i];}T const& operator[] (size_t i) const {return const_cast (*this)[i];}size_t size (void) const {return sizeof (m_a) / sizeof (m_a[0]);}private:T m_a[S];};//访问的都是共有成员,可以放在外面template ostream& operator<< (ostream& os,Array const& arr) {size_t size = arr.size ();for (size_t i = 0; i < size; ++i)os << '(' << arr[i]/*++*/ << ')';return os;}int main (void) {Array a;a[0] = 10;// a.operator[](0) = 10;a[1] = 20;a[2] = 30;cout << a << endl;Array b = a; // 拷贝构造cout << b << endl;Array c;c = b; // 拷贝赋值cout << c << endl;Array d;d[0] = "北京";d[1] = "上海";d[2] = "广州";cout << d << endl;Array > e;for (int i = 0; i < e.size (); ++i)for (int j = 0; j < e[i].size ();++j)e[i][j] = (i+1)*10+j+1;cout << e << endl;Array > > f;int const /*volatile*/ col = 4;Array , 1+1+1> g;for (int i = 0; i < g.size (); ++i)for (int j = 0; j < g[i].size ();++j)g[i][j] = (i+1)*10+j+1;for (int i = 0; i < g.size (); ++i) {for (int j = 0; j < g[i].size ();++j)cout << g[i][j] << ' ';cout << endl;}return 0;}
扩展用法
template<typename T> class Array; // 数组template<typename T> class List; // 链表Array<Array<int> > a; // 二维数组List<List<int> > b; // 二维链表Array<List<int> > c; // 链表数组List<Array<int> > d; // 数组链表template<typename T> class BiTree; // 二叉树BiTree<List<Array<int> > > e;6.特(例)化
如果一个类模板的通用实现针对某些特殊的类型实参,不能做出正确的处理,或者处理虽然可行但性能不佳,那么就可以针对该类型实参给出特殊的实现,以弥补通用版本的不足,这就叫类模板的特(例)化。1)全类(模板)特化template<>class 类模板名<类型实参1, 类型实参2, ...> { ... };2)成员特化template<>返回类型 类模板名<类型实参1,类型实参2, ...>::成员函数名 (调用实参表) { ... }注意,类模板的特化只是一种权宜之计,不应成为损失通用设计的借口。#include#include using namespace std;// 通用版本template T max (T x, T y) {return x < y ? y : x;}// 针对char*类型的重载版本char* max (char* x, char* y) {return strcmp (x, y) < 0 ? y : x;}// 通用版本template class Comparator {public:Comparator (T x, T y) :m_x (x), m_y (y) {}T max (void) const {return m_x < m_y ? m_y : m_x;}/*char* max (void) const {return strcmp (m_x, m_y) < 0 ?m_y : m_x;}*/private:T m_x, m_y;};// 针对char*类型的特化版本/*template<>class Comparator {public:Comparator (char* x, char* y) :m_x (x), m_y (y) {}char* max (void) const {return strcmp (m_x, m_y) < 0 ?m_y : m_x;}private:char* m_x, *m_y;};*/template<>char* Comparator ::max (void) const {return strcmp (m_x, m_y) < 0 ?m_y : m_x;}int main (void) {int a = 123, b = 345;cout << ::max (a, b) << endl;char c[] = "hello", d[] = "world";// cout << ::max (c, d) << endl;// cout << ::max (string (c),// string (d)) << endl;// cout << ::max (c, d) << endl;cout << ::max (c, d) << endl;Comparator ci (a, b);cout << ci.max () << endl;Comparator cs (c, d);cout << cs.max () << endl;return 0;}
7.局部(偏)特(例)化
1)只针对通用版本中的部分类型参数所做的特化被称为类模板的局部特化或偏特化。
2)类模板的局部特化只能以全类方式进行,不能只针对成员函数做特化。3)虽然没有强调类型参数取某种特定类型,但是强调类型参数之间的某种特殊关系或特殊属性,这种情况也属于局部特化。#include#include using namespace std;// 通用版本template class X {public:static void foo (void) {cout << "X " << endl;}};// 完全特化template<>class X {public:static void foo (void) {cout << "X " << endl;}};// 局部特化template class X {public:static void foo (void) {cout << "X " << endl;}};template class X {public:static void foo (void) {cout << "X " << endl;}};template class X {public:static void foo (void) {cout << "X " << endl;}};template class X {public:static void foo (void) {cout << "X " << endl;cout << typeid (A).name () << ' '<< typeid (B).name () < class X {public:static void foo (void) {cout << "X " << endl;}};int main (void) {X ::foo ();X ::foo ();X ::foo ();X ::foo ();X ::foo ();X ::foo ();X ::foo ();return 0;}
int i;
int* p = &i;int* q = p;8.智能指针
1)利用栈对象析构过程销毁堆对象;2)利用类模板做到类型无关;3)利用操作符重载模拟平凡指针的行为;4)利用转移拷贝避免double free异常;5)利用局部特化管理动态分配的对象数组。include#include #include using namespace std;class A {public:A (int data = 0) : m_data (data) {cout << "A构造:" << this < class AutoPtr {public:AutoPtr (T* p = NULL) : m_p (p) {}AutoPtr (AutoPtr& that) :m_p (that.release ()) {}AutoPtr& operator= (AutoPtr& that) {if (&that != this)reset (that.release ());return *this;}~AutoPtr (void) {delete m_p;}//返回对象本身用&,不是拷贝T& operator* (void) const {return *m_p;//m_p是指针,加上*,返回对象本身,即A}//*this返回调用对象本身,**this复用上面的*函数,&取地址T* operator-> (void) const {return &**this;}private:T* release (void) {T* p = m_p;m_p = NULL;return p;}void reset (T* p) {if (p != m_p) {delete m_p;m_p = p;}}T* m_p;};template class AutoPtr {public:AutoPtr (T* p = NULL) : m_p (p) {}AutoPtr (AutoPtr& that) :m_p (that.release ()) {}AutoPtr& operator= (AutoPtr& that) {if (&that != this)reset (that.release ());return *this;}~AutoPtr (void) {delete[] m_p;}T& operator* (void) const {return *m_p;}T* operator-> (void) const {return &**this;}private:T* release (void) {T* p = m_p;m_p = NULL;return p;}void reset (T* p) {if (p != m_p) {delete[] m_p;m_p = p;}}T* m_p;};int foo (void) {// A* pa = new A;// pa->m_data = 1000;// (*pa).foo ();// auto_ptr pa (new A);// smart_ptr pa (new A); // C++11AutoPtr pa (new A);pa->m_data = 1000;// pa.operator->()->m_data = 1000;(*pa).foo (); // 1000// pa.operator*().foo ();AutoPtr pb = pa; // 拷贝构造++pb->m_data;(*pb).foo (); // 1001AutoPtr pc (new A (2000));pb = pc; // 拷贝赋值++pb->m_data;(*pb).foo (); // 2001// ...FILE* fp = fopen ("none", "r");if (! fp) {perror ("fopen");// delete pa;return -1;}// ...fclose (fp);// ...// delete pa;return 0;}int main (void) {foo ();// auto_ptr pa (new A[3]);AutoPtr pa (new A[3]);return 0;}