C++函數(shù)模板與類模板相同與不同介紹_第1頁
C++函數(shù)模板與類模板相同與不同介紹_第2頁
C++函數(shù)模板與類模板相同與不同介紹_第3頁
C++函數(shù)模板與類模板相同與不同介紹_第4頁
C++函數(shù)模板與類模板相同與不同介紹_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第C++函數(shù)模板與類模板相同與不同介紹目錄1.模板1.1何為模板1.2C++的模板的形式有兩種1.3如何定義一個函數(shù)模板1.4語法形式1.5模板的編譯機制2.函數(shù)模板2.1調(diào)用方式2.2函數(shù)模板的特化與調(diào)用優(yōu)先級3.可變參函數(shù)模板3.1概念3.2代碼實現(xiàn)(實現(xiàn)一個c中的printf的函數(shù))4.類模板4.1類模板的定義形式4.2代碼實例5.類模板中的特殊屬性的初始化方式及繼承與多態(tài)5.1代碼實例5.2使用類模板去實現(xiàn)一個數(shù)據(jù)結(jié)構(gòu)5.3類模板的特化5.4C++中類模板中的內(nèi)嵌類

1.模板

1.1何為模板

即模子,生成器。

1.2C++的模板的形式有兩種

函數(shù)模板與類模板。

1.3如何定義一個函數(shù)模板

就像定義函數(shù)一樣,定義一個函數(shù)模板,把函數(shù)中類型抽象出來,

同時告訴編譯器下面的函數(shù)是一個函數(shù)模子或函數(shù)生成器。

1.4語法形式

template+classT1,classT2=double,classT3=int....

//模板頭中的類型參數(shù)列表也可以有默認值。

Tadd(Ta,Tb)

returna+b;

}

1.5模板的編譯機制

1.編譯器并不是把模板處理成能夠處理任何類型的函數(shù),而是一個函數(shù)或類的生成器。

2.函數(shù)模板通過具體類型產(chǎn)生不同的函數(shù)(產(chǎn)生了模板函數(shù))

3.編譯器會對函數(shù)模板進行兩次編譯,第一次在聲明的地方對模板本身進行編譯,在調(diào)用的地方對參數(shù)替換后的代碼進行編譯使用函數(shù)模板與真正的函數(shù),誰的調(diào)用效率高呢?當(dāng)然是真正的函數(shù),因為函數(shù)模板還需要編譯器進行翻譯一遍才能調(diào)用。所以現(xiàn)開發(fā)中并不一定要把所有函數(shù)你都要定義成函數(shù)模板,所以類型替換之后的函數(shù)模板就成了一個函數(shù)實例了,這樣才能調(diào)用。

代碼實例:

#includeiostream

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

returna+b;

intmain()

my_addint(10,20);

my_addfloat(3.14f,5.21f);

my_adddouble(5.21,3.14);

return0;

}

2.函數(shù)模板

2.1調(diào)用方式

顯式調(diào)用:函數(shù)名后使用尖括號指定具體參數(shù)調(diào)用。

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

returna+b;

intmain()

my_addint(10,20);

my_addfloat(3.14f,5.21f);

my_adddouble(5.21,3.14);

return0;

}

隱式調(diào)用:由編譯器自動根據(jù)參數(shù)推導(dǎo)參數(shù)類型再調(diào)用。

#includeiostream

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

returna+b;

intmain()

my_add(10,20);

my_add(3.14f,5.21f);

my_add(5.21,3.14);

return0;

}

2.2函數(shù)模板的特化與調(diào)用優(yōu)先級

當(dāng)只有基礎(chǔ)模板和特化模板時。

#includeiostream

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

cout"這是一個基礎(chǔ)模板"endl;

returna+b;

templateclassT

Tmy_add(inta,intb)

cout"這是一個特化模板"endl;

returna+b;

intmain()

coutmy_add(10,20)endl;

return0;

}

結(jié)果圖:

當(dāng)只有基礎(chǔ)模板和特化模板時,隱式調(diào)用基礎(chǔ)模板。

當(dāng)有基礎(chǔ)模板和特化模板,還有實例時候。

#includeiostream

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

cout"這是一個基礎(chǔ)模板"endl;

returna+b;

templateclassT

Tmy_add(inta,intb)

cout"這是一個特化模板"endl;

returna+b;

intmy_add(inta,intb)

cout"這是一個實例"endl;

returna+b;

intmain()

coutmy_add(10,20)endl;

return0;

}

結(jié)果圖:

當(dāng)有基礎(chǔ)模板和特化模板,還有實例時候,隱式調(diào)用用實例。

當(dāng)有基礎(chǔ)模板和特化模板,還有實例時候,顯示調(diào)用

#includeiostream

usingnamespacestd;

templateclassT

Tmy_add(Ta,Tb)

cout"這是一個基礎(chǔ)模板"endl;

returna+b;

templateclassT

Tmy_add(inta,intb)

cout"這是一個特化模板"endl;

returna+b;

intmy_add(inta,intb)

cout"這是一個實例"endl;

returna+b;

intmain()

coutmy_addint(10,20)endl;

return0;

}

結(jié)果圖:

當(dāng)有基礎(chǔ)模板和特化模板,還有實例時候,顯示調(diào)用用特化模板。

總結(jié):

當(dāng)有函數(shù)實例時:隱式調(diào)用將直接調(diào)用函數(shù)實例。

如果沒有函數(shù)實例時,隱式調(diào)用將直接調(diào)用函數(shù)模板的基礎(chǔ)模板。

如果使用顯示調(diào)用,當(dāng)優(yōu)先調(diào)用特化的與類型匹配的函數(shù)模板。

3.可變參函數(shù)模板

3.1概念

所謂的可變參模板是指類型參數(shù)為一一個可變是類型,這個類型使用class...來修飾。

3.2代碼實現(xiàn)(實現(xiàn)一個c中的printf的函數(shù))

#includeiostream

usingnamespacestd;

voidprintf()

templateclassFirstarg,class...Arg

voidprintf(Firstargfirstarg,Arg...arg)

coutfirstarg;

printf(arg...);

intmain()

printf("lisi","cc");

return0;

}

結(jié)果圖:

4.類模板

4.1類模板的定義形式

注意:在使用類模板時,不存在編譯推導(dǎo)類型,必須手動指定具體類型。

templateclassT1,classT2,classT3...

//class修飾符也可使用typename來修飾。

class+類名

//類模板的模板體。

private:

//類模板中的屬性。

public:

//類中的方法

protected:

};

4.2代碼實例

#includeiostream

usingnamespacestd;

templateclassT1,classT2

classA

T1name;

T2age;

public:

A(T1name,T2age)

this-age=age;

this-name=name;

voidshow_info()

cout"name="name",age="ageendl;

intmain()

//Astring,inta("lisi",20);

//a.show_info();

Astring,int*a=newAstring,int("lisi",20);

a-show_info();

return0;

}

結(jié)果圖:

5.類模板中的特殊屬性的初始化方式及繼承與多態(tài)

5.1代碼實例

#includeiostream

usingnamespacestd;

templateclassT1,classT2

classA

T1name;

T2age;

public:

A(T1name,T2age)

this-name=name;

this-age=age;

virtualvoidshow_info()

cout"name="this-name",age"ageendl;

voidset_name(T1name)

this-name=name;

T1get_name()

returnthis-name;

voidset_age(T2age)

this-age=age;

T2get_age()

returnthis-

templateclassT1,classT2,classT3

classB:publicAT1,T2

constintid;

staticintcount;

public:

B(T1name,T2age,T3_id):id(_id),AT1,T2(name,age)

voidshow_info()

cout"id="this-id",name="this-get_name()",age"this-get_age()endl;

intmain()

//1.棧上

Bstring,int,intb("lisi",20,1001);

b.show_info();

//2.堆上

Bstring,int,int*b1=newBstring,int,int("zhangsan",29,1002);

b1-show_info();

//3.實現(xiàn)多態(tài)

Astring,int*a=newBstring,int,int("wangwu",50,1003);

a-show_info();

return0;

}

結(jié)果圖:

5.2使用類模板去實現(xiàn)一個數(shù)據(jù)結(jié)構(gòu)

實現(xiàn)一個順序棧模板

首先我們使用一下多文件編程,類似于c的那種,我們會發(fā)現(xiàn)問題如下:

main.cpp文件:

#includeiostream

#include"socket.h"

usingnamespacestd;

intmain()

socketints(2);

return0;

}

stack.h文件:

#ifndefSOCKET_H

#defineSOCKET_H

usingnamespacestd;

#includeiostream

templateclassT

classsocket

T*m_date;

intlen;

intmax_size;

public:

//構(gòu)造

socket(int_len);

//析構(gòu)

~socket();

//入棧

voidpush(constsocketother);

//出棧

voidout();

//獲取棧頂?shù)闹?/p>

Tget_out();

//判斷是否為空

boolis_empty();

#endif//SOCKET_H

stack.cpp文件:

#include"socket.h"

templateclassT

socketT::socket(int_max_size)

this-m_date=newT[len];

this-len=0;

this-max_size=_max_size;

}

結(jié)果圖:

結(jié)果分析:如圖所以,結(jié)果告訴我們無法連接到構(gòu)造函數(shù),這是由于我們使用的是模板類,模板類需要被編譯兩次,如果我們像這樣把stack.cpp和stack.h分開寫的話,stack.cpp里面的模板只被編譯了一次,所以我們無法連接到構(gòu)造函數(shù)。

使分文件編程的方式實現(xiàn)一個模板棧:

在C++分文件編程時,在業(yè)內(nèi)常用的一種文件標準是后綴為.hpp的模板文件。

代碼實現(xiàn):

stack.cpp文件:

#ifndefSTACK_HPP

#defineSTACK_HPP

usingnamespacestd;

#includeiostream

templateclassT

classStack

T*my_data;

intlen;

intmax_size;

public:

//構(gòu)造函數(shù)

Stack(int_max_size);

//析構(gòu)函數(shù)

~Stack();

//入棧

voidpush(constintother);

//出棧

voidout_data();

//獲取棧頂?shù)闹?/p>

Tget_data();

//判斷是否為空

boolis_empty();

#endif//STACK_HPP

templateclassT

StackT::Stack(int_max_size)

this-my_data=newint[_max_size];

this-len=0;

this-max_size=_max_size;

templateclassT

StackT::~Stack()

if(this-my_data!=nullptr){

deletethis-my_data;

templateclassT

voidStackT::push(constintother)

if(this-max_sizelen){

return;

my_data[len]=other;

++(this-len);

templateclassT

voidStackT::out_data()

if(len=0){

return;

--(this-len);

templateclassT

TStackT::get_data()

returnthis-my_data[len-1];

templateclassT

boolStackT::is_empty()

if(this-len==0){

returntrue;

returnfalse;

}

main.cpp文件:

#includeiostream

#include"stack.hpp"

usingnamespacestd;

intmain()

Stackints(12);

s.push(1);

s.push(2);

s.push(3);

while(!s.is_empty()){

couts.get_data()endl;

s.out_data();

return0;

}

結(jié)果圖:

分析:因為這次我們把函數(shù)的實現(xiàn)放在了hpp文件里面,當(dāng)我們調(diào)用頭文件的時候問編譯一次,還有就是當(dāng)調(diào)用聲明的時候也會編譯一次,所以就達到了類模板的使用要求,所以這次我們就可以鏈接到。

5.3類模板的特化

#includeiostream

usingnamespacestd;

templateclassT1

classA

public:

cout"A的基礎(chǔ)模板"endl;

template

classAint

public:

cout"A的特化模板"endl;

templateclassT2,classT3

classB

public:

cout"B的基礎(chǔ)模板"endl;

templa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論