泛型程式設計 模板

2021-10-10 01:52:28 字數 3740 閱讀 3849

泛型程式設計

重點: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 開始,後面跟乙個模板引數列表...