C++中函數模板的概念和意義


1,對泛型編程進行學習,泛型編程是實際工程開發中必用的技術,大型公司的通用 庫都是采用泛型編程的技術完成的,C++ 中支持泛型編程技術,C++ 中的函數  模板和類模板就是 C++ 中泛型編程技術,本文分析 C++ 中的模板;

  

2,每一樣技術  的引入都是為了解決一定的問題,下面將通過一個例子讓大家意識到問題的存在,才能體會泛型編程的精妙之處;

 

3,C++ 中有幾種交換變量的方法?

    1,宏代碼塊;

    2,函數;

 

4,定義宏代碼塊 VS 定義函數(全局的):

   

5,變量的交換編程實驗:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 #define SWAP(t, a, b)    \  // 宏能夠完美的解決交換的問題,但是由於宏是預處理器處理的單元,也就是后續的編譯器根本不知道宏的存在,因此不建議用宏完成類似的函數功能,推薦直接寫函數;
 7 do                       \  
 8 {                        \
 9     t c = a;             \
10     a = b;               \
11     b = c;               \
12 }while(0)
13 
14 
15 void Swap(int& a, int& b)  // 要用引用來交換
16 {
17     int c = a;
18     a = b;
19     b = c;
20 }
21 
22 void Swap(double& a, double& b)
23 {
24     double c = a;
25     a = b;
26     b = c;
27 }
28 
29 void Swap(string& a, string& b)
30 {
31     string c = a;
32     a = b;
33     b = c;
34 }
35 
36 int main()
37 {
38 /*    
39     int a = 0;
40     int b = 1;
41     
42     Swap(int, a, b);
43     
44     cout << "a = " << a << endl;  // a = 1;
45     cout << "b = " << b << endl;  // b = 0;
46     
47     double m = 2;
48     double n = 3;
49     
50     Swap(double, m, n);
51     
52     cout << "m = " << m << endl;  // m = 3;
53     cout << "n = " << n << endl;  // n = 2;
54 */    
55     int a = 0;
56     int b = 1;
57     
58     Swap(a, b);
59     
60     cout << "a = " << a << endl;  // a = 1;
61     cout << "b = " << b << endl;  // b = 0;
62     
63     double m = 2;
64     double n = 3;
65     
66     Swap(m, n);
67     
68     cout << "m = " << m << endl;  // m = 3;
69     cout << "n = " << n << endl;  // n = 2;
70     
71     string d = "Delphi";
72     string t = "Tang";
73     
74     Swap(d, t);
75     
76     cout << "d = " << d << endl;  // d = Delphi;
77     cout << "t = " << t << endl;  // t = Tang;
78     
79     return 0;
80 }

    1,每當要交換兩個變量的值的時候,就需要重載 Swap() 函數,而 Swap() 函     數的程序邏輯一點改變都沒有,做的僅僅是復制粘貼改類型,這其實是重復的沒有技術含量的活;

    2,使用宏不安全、函數重載復制粘貼改類型,重復性勞動;

   

6,定義宏代碼塊:

    1,優點:代碼復用,適合所有的類型;

    2,缺點:編譯器不知道宏的存在,缺少類型檢查(不安全);

       定義函數:

   1,優點:真正的函數調用,編譯器對類型進行檢查;

   2,缺點:根據類型重復定義函數,無法代碼復用;

  

7,C++ 中有沒有解決方案集合兩種方法的優點?

    1,有,泛型編程;

   

8,泛型編程概念:

    1,不考慮具體數據類型的編程方式;

       1,對於 Swap 函數可以考慮下面的泛型寫法:

           1,代碼示例:

1 void Swap(T& a, T& b)
2 {
3     T t = a;
4     a = b;
5     a = t;
6 }

           2,Swap 泛型寫法中的 T 不是一個具體的數據類型,而是泛指任意的數據類型;

          

9,C++ 中泛型編程:

    1,函數模板:

       1,一種特殊的函數可用不同類型進行調用;

       2,看起來和普通函數很相似,區別是類型可被參數化:

           1,代碼示例:

1 template<typename T>  // 定義了一個模板,里面有一個類型名 T,泛指各種類型;
2 void Swap(T& a, T& b)
3 {
4     T t = a;
5     a = b;
6     b = t;
7 }       

       3,函數模板的語法規則:

           1,template 關鍵字用於聲明開始進行泛型編程;

           2,typename 關鍵字用於聲明泛指類型;

       4,函數模板的使用:

           1,自動類型推導調用;

              1,根據實參類型進行推導;

           2,具體類型顯示調用;

1 int a = 0;
2 int b = 1;
3                    
4 Swap(a, b);  // 自動推導;根據參數自動推導模板中的 T 應該為 int 類型;
5                    
6 float c = 2;
7  float d = 3;
8                    
9 Swap<float>(c, d);  // 顯示調用;顯示告訴函數模板中的 T 是一個 float 類型;

                

10,函數模板使用初探編程實驗:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 template < typename T >  // 開始泛型編程,泛指類型是 T;在下面函數定義中用 T 可以代表類型;
 7 void Swap(T& a, T& b)
 8 {
 9     T c = a;
10     a = b;
11     b = c;
12 }
13 
14 template < typename T >
15 void Sort(T a[], int len)
16 {
17     for(int i=0; i<len; i++)
18     {
19         for(int j=i; j<len; j++)
20         {
21             if( a[i] > a[j] )
22             {
23                 Swap(a[i], a[j]);
24             }
25         }
26     }
27 }
28 
29 template < typename T >
30 void Println(T a[], int len)
31 {
32     for(int i=0; i<len; i++)
33     {
34         cout << a[i] << ", ";
35     }
36     
37     cout << endl;
38 }
39 
40 int main()
41 {
42     /* 以下是交換數據函數模板測試代碼 */
43     int a = 0;
44     int b = 1;
45     
46     Swap(a, b);  // 自動推導,等價於 Swap<int>(a, b);
47     
48     cout << "a = " << a << endl;  // a = 1;
49     cout << "b = " << b << endl;  // b = 0;
50     
51     double m = 2;
52     double n = 3;
53     
54     Swap(m, n);  // 自動推導,等價於 Swap<double>(a, b);
55     
56     cout << "m = " << m << endl;  // m = 3;
57     cout << "n = " << n << endl;  // n = 2;
58     
59     string d = "Delphi";
60     string t = "Tang";
61     
62     Swap<string>(d, t);  //顯示指定;將 T 替換成 string,然后進行調用;
63     
64     cout << "d = " << d << endl;  // d = Delphi;
65     cout << "t = " << t << endl;  // t = Tang;
66 
67     /* 以下是選擇排序算法測試代碼 */
68         
69     int a[5] = {5, 3, 2, 4, 1};
70     
71     Println(a, 5);  // 5, 3, 2, 4, 1
72     Sort(a, 5);  // 自動推導
73     Println(a, 5);  // 1, 2, 3, 4, 5
74     
75     string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"};
76     
77     Println(s, 5);  // Java, C++, Pascal, Ruby, Basic,
78     Sort(s, 5);
79     Println(s, 5);  // Basic, C++, Java, Pascal, Ruby,
80     
81     return 0;
82 }

    1,使用函數模板程序中代碼復用率大大增加;

    2,大公司中自己通用庫都是使用泛型編程、模板技術來完成的;

    3,模板技術、泛型編程,非常適合於用來寫算法,通用庫都是使用模板技術完成;

   

11,小結:

    1,函數模板是泛型編程在 C++ 中的應用方式之一;

       1,之二是類模板;

    2,函數模板能夠根據實參對參數類型進行推導;

    3,函數模板支持顯示的指定參數類型;

    4,函數模板是 C++ 中重要的代碼復用方式;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM