c++中的类(class)-----笔记(类模板)

1,一个类模板至少具有一个类参数,类参数是个符号以表示将要被某个确定数据类型代替的类型。

 1 #include<iostream>
 2 #include<string>
 3 
 4 using namespace std;
 5 
 6 template <class T>
 7 class Array {
 8     public:
 9         T& operator [](int);
10         const T& operator [](int);
11         Array(int);
12         ~Array();
13         int get_size() const { return size;}
14     private:
15         char* a;
16         int size;
17         Array();    // 实例化的时候必须给出大小 
18         T dummy_val;
19 };
20 
21 template<class T>
22 T& Array<T>::operator [](int i) {
23     if(i < 0 || i >= size) {
24         cerr << "index  "<<i<<"  out of bounds! ";
25         return dummy_val;
26     }
27     return a[i];
28 } 
29 
30 template<class T>
31 T& Array<T>::operator [](int i) const {
32     if(i < 0 || i >= size) {
33         cerr << "index  "<<i<<"  out of bounds! ";
34         return dummy_val;
35     }
36     return a[i];
37 } 
38 
39 template<class T>
40 Array<T>::Array(int s) {
41     a = new T[size = s];
42 }
43 
44 template<class T>
45 Array<T>::~Array() {
46     delete[] a;
47 }
48 
49 template<class T>
50 ostream operator<<(ostream& os,const Array<T>& arr) {  // 顶层函数重载 
51     for(int i=0;i<arr.get_size();++i)
52         os<<arr[i]<<endl;
53     return os;
54 }
模板类示例

由于 Array 类的参数化构造函数与重载的下标操作符在类声明之外定义,因此需要在定义之前加上模板头:template <class T>。

由于 Array 是个模板类,因此类名是 Array<T>,这里 T 是模板头的类参数。

 

2,类模板可以拥有多个类参数,这些参数用逗号隔开。每个类参数前都必须有关键字 class 或 typename。

1 template<class T1,class T2,class T3>
2 class Sample {
3     public:
4         T2 m(T3 p) { } // expects a T3 arg,returns a T2
5     private:
6         T1 x;     // var of type T1
7 }; 
多个类参数示例

 

3,模板实例:我们通过 < > 中指定数据类型来使用一个模板类。

1 int main() {
2     Array<int> a1(10);  // Array of 10 int
3     
4     return 0;
5 }
模板实例

以上语法表面用 int 来替换模板类 Array 声明的类参数 T,编译器会将在 Array 声明中所有的类参数 T 替换成 int。

用内建的或自定义的数据类型都可以创建模板实例

1 class Task {  // user-defined data type
2     //...
3 };
4 
5 Array<Task> tasks(10); 
自定义类型实例

 

4,一个对象不能属于像 Array 或 Array<T> 的对象,但我们可以定义类型为 Array<int> 的对象。

 

5,参数表中的类模板:类模板可以作为一种数据类型出现在参数表中。

1 template<class T>
2 ostream operator<<(ostream& os,const Array<T>& arr) {  // 顶层函数重载 
3     for(int i=0;i<arr.get_size();++i)
4         os<<arr[i]<<endl;
5     return os;
6 }
模板类作为参数

 

6,模板的函数式参数:类模板必须至少有一个类参数,当然可以有多个类参数。类模板、还可以有非类参数的参数,一般称之为函数类型参数,一个模板类可以有多个函数类型参数,所有的参数用逗号分开。

1 template<class T,int x,float Y>
2 class Sample {
3     //...
4 };
函数式参数

 

7,示例程序:模板堆栈类

  1 // stack
  2 template<class T>
  3 class Stack {
  4     public:
  5         enum{ DefaultSize = 50,EmptyStack = -1};
  6         Stack();
  7         Stack(int);
  8         ~Stack();
  9         void push( const T&);
 10         T pop();
 11         T getNoPop() const;
 12         bool empty() const;
 13         bool full() const;
 14     private:
 15         T* elements;
 16         int top;
 17         int size;
 18         void allocate() {
 19             elements = new T[size];
 20             top = EmptyStack;
 21         }
 22         void msg(const char* m) const {
 23             cout << "*****  "<<m<<"  *****"<<endl;
 24         }
 25         template<class T>
 26         friend ostream& operator<<(ostream& os,const Stack<T>&);
 27 };
 28 
 29 // Stack 类的实现
 30  template<class T>
 31  Stack<T>::Stack() {
 32      size = DefaultSize;
 33      allocate();
 34  }
 35  
 36 template<class T>
 37 Stack<T>::Stack(int s) {
 38     if(s < 0)
 39         s *= -1;
 40     else if(s == 0)
 41         size = DefaultSize;
 42     size = s;
 43     allocate();
 44 }
 45 
 46 template<class T>
 47 Stack<T>::~Stack() {
 48     delete[] elements;
 49 } 
 50  
 51 template<class T>
 52 void Stack<T>::push(const T& e) {
 53     assert(!full());
 54     if(!full())
 55         elements[++top] = e;
 56     else
 57         msg("Stack full!");
 58 }
 59 
 60 template<class T>
 61 T Stack<T>::pop() {
 62     assert(!empty());
 63     if(!empty())
 64         return elements[top--];
 65     else {
 66         msg("Stack empty!");
 67         T dummy_val;
 68         return dummy_val;  // 返回一个不确定的值 
 69     }    
 70 }
 71 
 72 template<class T>
 73 T Stack<T>:: getNoPop() const {
 74     assert(top > EmptyStack);
 75     if(!empty)
 76         return elements[top];
 77     else {
 78         msg("Stack empty!");
 79         T dummy_val;
 80         return dummy_val;
 81     }
 82 }
 83 
 84 template<class T>
 85 bool Stack<T>::empty() const {
 86     return top <= EmptyStack;
 87 }
 88 
 89 template<class T>
 90 bool Stack<T>::full() const {
 91     return top + 1 >= size;
 92 }
 93 
 94 template<class T>
 95 ostream& operator<<(ostream& os,const Stack<T>& s) {
 96     s.msg("Stack contents:");
 97     int t = s.top;
 98     while(t > s.EmptyStack) 
 99         cout<<s.elements[t--]<<endl;
100     return os;
101 }
102 
103 int main() {
104     Stack<int> stk(1);
105     stk.push(1);
106     cout<<stk<<endl;
107     
108     return 0;
109 }
Stack 类的实现

 

8,函数模板

 1 #include <iostream>
 2 #include <stack>
 3 using namespace std;
 4 
 5 // this is a function template
 6 template<class Type>
 7 Type maxValue(Type a,Type b) {
 8     return a > b ? a : b;
 9 }
10 
11 int main(){
12     stack<int> intStack;  // 类模板的实例化只能由程序员显式指定
13     cout <<"模板函数隐式调用:" << maxValue(1,2) << endl;
14     cout << "模板函数显式调用:" << maxValue<double>(1.1,2.2) <<endl;
15     return 0;
16 }
类模板和函数模板实例

note:类模板只能通过显式的调用生成模板类; 函数模板可以通过显式调用或隐式调用生成模板函数。

posted on 2019-03-06 17:19  爱笑的张飞  阅读(1395)  评论(0编辑  收藏  举报

导航