泛型程式設計
重點:1.熟悉模板的語法
2.模板的原理
3.理解 基礎語法+類和物件+模板 去解決c語言不足的問題和意義
使用模板, 編寫跟型別無關的**
例如在一些函式和類的時候,針對不同型別需要寫很多重複的**(swap函式)
類:比如我們想實現乙個資料結構棧stack,stack的多個物件,st1存int,st2存double,等等。
解決方案:
1.函式模板
template
void swap(t& a, t& b)
2.類模板
template
class stack
模板的原理
編譯器根據呼叫函式模板和類模板的型別,例項化出對應的函式和類
編譯器是把例項化生成的函式和類放到程序的**段去執行 (模板不是指令)
c語言和c++優缺點:
忘記初始化和銷毀----> 建構函式和析構函式
沒有封裝,誰都可以修改結構體的資料----> 類 + 訪問限定符
如果想同時定義兩個棧,乙個棧存int,乙個棧存double,做不到---->模板
引用傳參:1. 修改傳遞的實參比如swap 2.減少拷貝
引用傳返回值:1.修改返回物件如operator[ ] 2.減少拷貝
**如下:
#include
#include
using
namespace std;
//template
//class stack_cpp
//// ~stack_cpp()
// {}
// void push(t x)
// {}
//private:
// t* _a;
// int _size;
// int _capacity;
//};
//template
//class seqlist;
template
<
class
t>
class
vector
//動態增長的陣列
~vector()
//類裡面宣告
void
push_back
(const t& x)
;void
pop_back()
; size_t size()
t&operator
(size_t i)
//加引用,避免產生的臨時物件(具有常性)不能被修改
private
: t* _a;
size_t _size;
size_t _capacity;};
//類外面定義
template
<
class
t>
void vector
::push_back
(const t& x)
_a = tmp;
_capacity = newcapacity;
} _a[_size]
= x;
++_size;
}template
<
class
t>
void vector
::pop_back()
intmain()
cout << endl;
return0;
}
模板的特化
函式模板特化的步驟:
必須要先有乙個基礎的函式模板
關鍵字template後面接一對空的尖括號<>
函式名後跟一對尖括號,尖括號中指定需要特化的型別
函式形參表: 必須要和模板函式的基礎引數型別完全相同,如果不同編譯器可能會報一些奇怪的錯誤。
例如:
template
<
class
t>
bool
isequal
(t& left, t& right)
//字串型別的特化
template
<
>
bool isequal<
char
*>
(char
*& left,
char
*& right)
模板引數分為非型別模板引數和模板引數
型別形參:出現在模板引數列表中,跟在class或者typename之類的引數型別名稱。
非型別形參:就是用乙個常量作為類(函式)模板的乙個引數,在類(函式)模板中可將該引數當成常量來使用。非型別模板引數只能接受整數或者類整數:
浮點數、類物件以及字串是不允許作為非型別模板引數的。
非型別的模板引數必須在編譯期就能確認結果。
類模板的特化:全特化和半特化(偏特化)
全特化即是將模板引數列表中所有的引數都確定化。
template
<
classt1,
class
t2>
class
data
private
: t1 _d1;
t2 _d2;};
//1.必須要有乙個普通的類模板
//template<>
//class data
//private:
// int _d1;
// char _d2;
//};
偏特化:任何針對模版引數進一步進行條件限制設計的特化版本。
template
<
classt1,
class
t2>
class
data
private
: t1 _d1;
t2 _d2;};
//半特化
//1.特化部分型別
template
<
class
t>
class
data
char
>
private
: t _d1;
char _d2;};
//半特化
//2.對模板引數做進一步的限制
template
<
classt1,
class
t2>
class
data
, t2*
>
private
: t1 _d1;
t2 _d2;
};
模板分離編譯
注意!!!
模板不支援分離編譯
分離編譯是指乙個程式(專案)由若干個原始檔共同實現,而每個原始檔單獨編譯生成目標檔案,最後將所有目標檔案鏈結起來形成單一的可執行檔案的過程。
因為預處理,編譯,彙編都沒有實現互動,所以會導致編譯器沒有將模板函式進行例項化,但是編譯器在鏈結時才會找函式的位址。
這就導致編譯器會報鏈結錯誤,例如:
所以最好將模板的宣告和定義放在同乙個檔案中,例如放在.hpp中,也或者在模板宣告的地方將模板例項化
總結模板復用了**,節省資源,更快的迭代開發,增加了**的靈活性
可以理解為編譯時的多型
模板 泛型程式設計
我們從乙個很簡單的問題來進入泛型程式設計 question 如何寫乙個通用的加法函式 使用函式過載。針對每乙個所需相同行為的不同型別重新實現 函式過載的缺點 1 只要有 型別出現,就要重新新增對應函式 2 除型別外,所有函式的函式體都相同,的復用率不高 3 如果函式知識返回值型別不同,函式過載不能解...
模板和泛型程式設計
在建立完成抽象操作的函式時,如 拷貝,反轉和排序,你必須定義多個版本以便能處理每一種資料型別。以比較兩個數的大小為例 includeusing namespace std int max int a,int b double max double a,double b int main 例如 tem...
模板與泛型程式設計
模板是泛型變成的基礎。泛型程式設計 編譯與型別無關的 是一種復用的方式,模板分為模板函式和模板類。模板函式是乙個通用的函式模板,而不是為每一種型別定義乙個新函式,乙個函式模板就像乙個公式,針對不同型別函式生成不同的函式版本。關鍵字 template 以 template 開始,後面跟乙個模板引數列表...