国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

感受C++模版的所帶來的魅力

這篇具有很好參考價(jià)值的文章主要介紹了感受C++模版的所帶來的魅力。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、泛型編程思想

  • 首先我們來看一下下面這三個(gè)函數(shù),如果學(xué)習(xí)過了?C++函數(shù)重載?和?C++引用?的話,就可以知道下面這三個(gè)函數(shù)是可以共存的,而且傳值會(huì)很方便
  • void Swap(int& left, int& right)
    {
    	int temp = left;
    	left = right;
    	right = temp;
    }
    void Swap(double& left, double& right)
    {
    	double temp = left;
    	left = right;
    	right = temp;
    }
    void Swap(char& left, char& right)
    {
    	char temp = left;
    	left = right;
    	right = temp;
    }
    

但是真的很方便嗎?這里只有三種類型的數(shù)據(jù)需要交換,若是我們需要增加交換的數(shù)據(jù)呢?再CV然后寫一個(gè)函數(shù)嗎?

?這肯定是不現(xiàn)實(shí)的,所以很明顯函數(shù)重載雖然可以實(shí)現(xiàn),但是有一下幾個(gè)不好的地方:

  1. 重載的函數(shù)僅僅是類型不同,代碼復(fù)用率比較低,只要有新類型出現(xiàn)時(shí),就需要用戶自己增加對(duì)應(yīng)的函數(shù)
  2. 代碼的可維護(hù)性比較低,一個(gè)出錯(cuò)可能所有的重載均出錯(cuò)

?那是否能做到這么一點(diǎn),告訴編譯器一個(gè)模子,讓編譯器根據(jù)不同的類型利用該模子來生成代碼
這樣,我們先通過一個(gè)案例來做引入

  • 才高八斗的魏武帝之子【曹植】曾經(jīng)寫過一首《洛神賦》,被后人譽(yù)為“千古第一絕世神仙詩”,因此在那個(gè)時(shí)候被很多文人所抄錄、傳唱,其共1089個(gè)字,想要一字不落地抄錄下來還是需要時(shí)間,那古代還有一些更長(zhǎng)的詩賦,例如:《離騷》,足足有2500多字,若也是一個(gè)一個(gè)地抄錄下來的話,那會(huì)變得極為麻煩

感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

  • 于是呢古人又發(fā)明了一種東西叫做【活字印刷術(shù)】,有了此技術(shù)之后,人們不再需要每次去手抄一些詩賦書籍,只需要作一份模版字體,然后在其上刷上水,刷上墨,然后拿紙這么一印,就可以得到一份工整的印刷體了感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

???? 所以,總結(jié)上面的這么一個(gè)技術(shù),C++的祖師爺呢就想到了【模版】這個(gè)東西,告訴編譯器一個(gè)模子,然后其余的工作交給它來完成,根據(jù)不同的需求生成不同的代碼

這就是??泛型編程:編寫與類型無關(guān)的通用代碼,是代碼復(fù)用的一種手段。模板是泛型編程的基礎(chǔ)

二、函數(shù)模版

知曉了模版的基本概念后,首先我們要來看的就是【函數(shù)模版】

1、函數(shù)模板概念

函數(shù)模板代表了一個(gè)函數(shù)家族,該函數(shù)模板與類型無關(guān),在使用時(shí)被參數(shù)化,根據(jù)實(shí)參類型產(chǎn)生函數(shù)的特定類型版本

通過函數(shù)模板,可以編寫一種通用的函數(shù)定義,使其能夠適用于多種數(shù)據(jù)類型,從而提高代碼的復(fù)用性和靈活性。

2、函數(shù)模板格式

  • 然后正式來聲明一個(gè)函數(shù)模版,這里我們要學(xué)一個(gè)新的關(guān)鍵字叫template,接下去加一個(gè)<>尖括號(hào),內(nèi)部就是模版的參數(shù)了,可以使用typename或者class來進(jìn)行類型的聲明(不可以用struct),若是只有一個(gè)類型的話我們一般會(huì)叫做【T】,不過這個(gè)沒有強(qiáng)制要求
template<typename T1, typename T2,......,typename Tn>
  • 接下去就可以使用上面所聲明的模版參數(shù)了,即上面的這個(gè)【T】,它和我們普通的函數(shù)參數(shù)可不一樣,后者是定義的是對(duì)象,而前者定義的是類型
    返回值類型 函數(shù)名(參數(shù)列表){}
    

    馬上,我們就來為上面的swap()函數(shù)寫一個(gè)通用的函數(shù)模版把

    template<typename T>
    void Swap(T& left, T& right)
    {
    	T temp = left;
    	left = right;
    	right = temp;
    }
    
  • 然后來用一用這個(gè)函數(shù)模版,分別傳入不同數(shù)據(jù)類型的參數(shù),通過結(jié)果的觀察可以發(fā)現(xiàn)這個(gè)函數(shù)模版可以根據(jù)不同的類型去做一個(gè)自動(dòng)推導(dǎo),繼而去起到一個(gè)交換的功能感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)
  • 我們可以通過調(diào)試來進(jìn)一步觀察,發(fā)現(xiàn)無論是對(duì)于【整型】還是【浮點(diǎn)型】,都會(huì)去走這個(gè)Swap()函數(shù),函數(shù)模版都可以進(jìn)行自動(dòng)的識(shí)別感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

?那我現(xiàn)在想問一個(gè)問題,請(qǐng)問它們調(diào)用的真的是同一個(gè)函數(shù)嗎?

  • ?相信很多同學(xué)都說是的,上面不是演示過了嗎?但是看完下面這一小節(jié)你就不會(huì)這么說了??

?3、函數(shù)模板的原理

接下去我們來說說這個(gè)函數(shù)模版的原理,帶你理清編譯器內(nèi)部究竟做了什么事情

  • 對(duì)于函數(shù)模板而言其實(shí)是一個(gè)【藍(lán)圖】,它本身并不是函數(shù),是編譯器用使用方式產(chǎn)生特定具體類型函數(shù)的模具。所以其實(shí)模板就是將本來應(yīng)該我們做的重復(fù)的事情交給了編譯器,讓我們來看看編譯器做了什么
    感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)
  • 可以發(fā)現(xiàn),在進(jìn)行匯編代碼查看的時(shí)候,被調(diào)用的函數(shù)模版生成了兩個(gè)不同的函數(shù),它們有著不同的函數(shù)地址,因此可以回答上一小節(jié)所提出的問題了,兩次所調(diào)用的函數(shù)是不一樣的,是根據(jù)函數(shù)模版所生成的

還是不太懂的老鐵可以看看下面這張圖,就能明白了

  • 在編譯器編譯階段,對(duì)于模板函數(shù)的使用,編譯器需要根據(jù)傳入的實(shí)參類型來推演生成對(duì)應(yīng)類型的函數(shù)以供調(diào)用。比如:當(dāng)用int類型使用函數(shù)模板時(shí),編譯器通過對(duì)實(shí)參類型的推演,將T確定為int類型,然后產(chǎn)生一份專門處理int類型的代碼,對(duì)于浮點(diǎn)類型、字符型也是如此感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

??? 那我現(xiàn)在還想問,如果我使用的是兩個(gè)日期類Date的對(duì)象呢,能不能對(duì)它們進(jìn)行交換

  • ?答案是可以的,int、double、char這些都是內(nèi)置類型,Date呢是自定義類型,很明顯它們都是類型,我們所定義的模版參數(shù)也是類型,那為何不可去做一個(gè)接受呢?從運(yùn)行結(jié)果可以來看,確實(shí)是可以發(fā)現(xiàn)它們也發(fā)生了一個(gè)交換感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

?? 那如果是指針呢?也會(huì)去調(diào)用嗎?

  • ?如何你學(xué)的扎實(shí)得話,立馬就能反應(yīng)過來了,對(duì)于指針而言也是內(nèi)置類型,那既然是類型的話為何不能調(diào)用呢?感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

既然談到了這個(gè)【Swap】交換函數(shù),我們就順便來說說庫里的這個(gè)【swap】

  • 仔細(xì)觀察下圖可以發(fā)現(xiàn)我將Swap前面大寫S改成了小寫s,它就是std標(biāo)準(zhǔn)庫的里面的一個(gè)函數(shù),也包含在STL的基本算法中感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)
  • 進(jìn)到文檔里面進(jìn)行查看我們可以發(fā)現(xiàn)這個(gè)函數(shù)確實(shí)已經(jīng)實(shí)現(xiàn)了【函數(shù)模版】,因此可以接收任何類型的數(shù)據(jù),所以在學(xué)習(xí)了函數(shù)模版后我們就不需要自己再去寫swap()函數(shù)了,直接用庫里的即可感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

4、函數(shù)模板的實(shí)例化

上面我們所定義的都是單個(gè)模版參數(shù),那多個(gè)模版參數(shù)是否可以定義呢?

  • 這個(gè)當(dāng)然是可以的,我們立馬來試試看吧
    template<typename T1, typename T2>
    T1 Func(const T1& x, const T2& y)
    {
    	cout << x << " " << y << endl;
    }
    
  • 通過運(yùn)行可以發(fā)現(xiàn),是完全可以做到的,去定義多個(gè)模版參數(shù),這個(gè)特性本文就不做距離了,等我們學(xué)習(xí)了一些STL之后再【模版進(jìn)階】一文中詳解感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

然后我們來講講【函數(shù)模板的實(shí)例化】

?? 用不同類型的參數(shù)使用函數(shù)模板時(shí),稱為函數(shù)模板的實(shí)例化。模板參數(shù)實(shí)例化分為:隱式實(shí)例化顯式實(shí)例化

  1. 隱式實(shí)例化:讓編譯器根據(jù)實(shí)參推演模板參數(shù)的實(shí)際類型
  • 知道模版可以定義多個(gè)參數(shù)之后,其返回值也可以是模版參數(shù)
    template<class T>
    T Add(const T& left, const T& right)
    {
    	return left + right;
    }
    
  • 下面這種就是【隱式實(shí)例化】,讓編譯器根據(jù)實(shí)參自動(dòng)去推導(dǎo)模板參數(shù)的實(shí)際類型,然后返回返回不同類型的數(shù)據(jù)
    int main()
    {
    	int a1 = 10, a2 = 20;
    	double d1 = 10.0, d2 = 20.0;
    	// 根據(jù)實(shí)參傳遞的類型,推演T的類型
    	cout << Add(a1, a2) << endl;
    	cout << Add(d1, d2) << endl;
    }
    

    感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

  • 但是呢像下面這種就不可以了,因?yàn)閍1是【int】類型,d1是【double】類型,在編譯期間,當(dāng)編譯器看到該實(shí)例化時(shí),需要推演其實(shí)參類型 通過實(shí)參a1將T推演為int類型,通過實(shí)參d1將T推演為double類型,但模板參數(shù)列表中只有一個(gè)T, 編譯器無法確定此處到底該將T確定為int 或者 double類型而報(bào)錯(cuò)。此時(shí)在函數(shù)調(diào)用完后進(jìn)行返回時(shí),編譯器也識(shí)別不出是哪個(gè)類型了,它們兩個(gè)就像在打架一樣,很難一絕高下

    cout << Add(a1, d2) << endl
    

    感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

    好比你做錯(cuò)事了,你爸爸讓你罰站,不讓你吃飯,此時(shí)呢你媽媽回來了,讓你趕緊過來吃飯,那此時(shí)你該聽誰的呢?

  • 那此時(shí)呢就需要爸爸媽媽回房間商量一下了,到底是以誰說的話為主呢感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

那當(dāng)他們商量好了之后,就會(huì)有下面這兩種情況

  • 這一種改法便是聽爸爸的,后者d1強(qiáng)轉(zhuǎn)為int類型然后再傳遞進(jìn)去,此時(shí)就不會(huì)出現(xiàn)類型沖突的問題了
    cout << Add(a1, (int)d2) << endl;
    
  • 這種改法便是聽媽媽的,前者a1強(qiáng)轉(zhuǎn)為double類型然后再傳遞進(jìn)去,也不會(huì)出現(xiàn)類型沖突的問題
    cout << Add((double)a1, d2) << endl;
    
  1. 顯式實(shí)例化:在函數(shù)名后的<>中指定模板參數(shù)的實(shí)際類型
  • 除了上面這種手動(dòng)強(qiáng)轉(zhuǎn)的措施,還有一種辦法就是我們自己進(jìn)行【顯式實(shí)例化】,如何你還有印象的話,可以翻上看看匯編,其實(shí)編譯器在底層就是轉(zhuǎn)換為了這種形式
// 顯式實(shí)例化,用指定類型實(shí)例化
cout << Add<int>(a1, d2) << endl;
cout << Add<double>(a1, d2) << endl;

感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

雖然上面我們介紹了兩種處理方式,但是對(duì)于某些場(chǎng)景來說,卻只能進(jìn)行【顯式實(shí)例化】

  • 例如我在下面寫了一個(gè)函數(shù)模版,形參部分并不是模版參數(shù),而是普通的自定義類型,之后返回值才是,那此時(shí)我們就無法通過傳參來指定這個(gè)【T】的類型,只能有外部在調(diào)用這個(gè)模版的時(shí)候顯示指定
    template<class T>
    T* Alloc(int n)
    {
    	return new T[n];
    }
    
  • 例如下面的這些,我們想開什么數(shù)據(jù)類型的空間,只需要顯示指定類型即可
    // 有些函數(shù)無法自動(dòng)推,只能顯示實(shí)例化
    double* p1 = Alloc<double>(10);
    float* p1 = Alloc<float>(20);
    int* p2 = Alloc<int>(30);
    

    5、模板參數(shù)的匹配原則

① 一個(gè)非模板函數(shù)可以和一個(gè)同名的函數(shù)模板同時(shí)存在,而且該函數(shù)模板還可以被實(shí)例化為這個(gè)非模板函數(shù)

  • 可以看到,我在下面寫了一個(gè)專門處理int的加法函數(shù),為普通的函數(shù),又寫了一個(gè)函數(shù)模版,它們是可以進(jìn)行共存的,在進(jìn)行普通傳參的時(shí)候,就會(huì)去調(diào)用這個(gè)普通的Add函數(shù);若是顯式指明了類型的話,就會(huì)去調(diào)用這個(gè)函數(shù)模版讓編譯器生成對(duì)應(yīng)的函數(shù)
    // 專門處理int的加法函數(shù)
    int Add(int left, int right)
    {
    	return left + right;
    }
    
    // 通用加法函數(shù)
    template<class T>
    T Add(T left, T right)
    {
    	return left + right;
    }
    
    int main(void)
    {
    	Add(1, 2);
    	Add<int>(1, 2);
    	return 0;
    }
    

    感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

    ②?對(duì)于非模板函數(shù)和同名函數(shù)模板,如果其他條件都相同,在調(diào)動(dòng)時(shí)會(huì)優(yōu)先調(diào)用非模板函數(shù)而不會(huì)從該模板產(chǎn)生出一個(gè)實(shí)例。如果模板可以產(chǎn)生一個(gè)具有更好匹配的函數(shù), 那么將選擇模板

  • 也是和上面類似的代碼,不過對(duì)于函數(shù)模版這一塊我使用到了兩個(gè)模版參數(shù),就是為了匹配多種數(shù)據(jù)類型
// 專門處理int的加法函數(shù)
int Add(int left, int right)
{
	return left + right;
}

// 通用加法函數(shù)
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
	return left + right;
}

int main(void)
{
	Add(1, 2);
	Add(1, 2.2);
	return 0;
}
  • 觀察調(diào)試結(jié)果我們可以發(fā)現(xiàn)Add(1, 2)優(yōu)先去調(diào)了普通的加法函數(shù),因?yàn)閭鬟f進(jìn)去的是兩個(gè)【int】類型的參數(shù),完全吻合;但是呢對(duì)于第二個(gè)Add(1, 2.2)來說,卻去調(diào)用了函數(shù)模版,因?yàn)榈诙€(gè)參數(shù)是【double】類型,普通的函數(shù)它也接不住呀,此時(shí)模版參數(shù)就可以根據(jù)這個(gè)類型來進(jìn)行一個(gè)自動(dòng)推導(dǎo)感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

③ 模板函數(shù)不允許自動(dòng)類型轉(zhuǎn)換,但普通函數(shù)可以進(jìn)行自動(dòng)類型轉(zhuǎn)換

  • 首先對(duì)于普通函數(shù)而言很好理解,看到print函數(shù)的形參所給的類型為【int】,但是在外界傳入了一個(gè)【double】類型的數(shù)值,如果你學(xué)習(xí)過 隱式類型轉(zhuǎn)換 的話,就可以知道這個(gè)浮點(diǎn)數(shù)傳入的話會(huì)發(fā)生一個(gè)轉(zhuǎn)換,這就叫做【自動(dòng)類型轉(zhuǎn)換】
    // 普通函數(shù),允許自動(dòng)類型轉(zhuǎn)換
    void print(int value) {
        std::cout << "Integer: " << value << std::endl;
    }
    
    int main() {
        print(3);	
        print(3.14); 
        return 0;
    }
    
  • 但是呢,對(duì)于模版函數(shù)來說是無法進(jìn)行自動(dòng)類型轉(zhuǎn)換的,例如下面這個(gè),我為這個(gè)函數(shù)模版定義了一個(gè)模版參數(shù),但是在外界進(jìn)行傳遞的時(shí)候卻傳遞進(jìn)來兩種數(shù)據(jù)類型,為【int】或【double】,那么一個(gè)模版參數(shù)T就使得編譯器無法去進(jìn)行自動(dòng)推導(dǎo)
    template <class T>
    void print(T a, T b) {
        cout << a << " " << b << endl;
    }
    
    int a = 1;
    double b = 1.11;
    
    print(a, b);
    

感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

  • 這個(gè)其實(shí)我們?cè)谏厦嬉仓v到過,再來回顧一下,改進(jìn)的方法有兩種,一個(gè)是【強(qiáng)制類型轉(zhuǎn)換】,還記得罰站的事情嗎;另一個(gè)則是【顯式實(shí)例化】,還記得我們看的匯編嗎
    // 強(qiáng)制類型轉(zhuǎn)換
    print(a, (int)b);
    print((double)a, b);
    // 顯式實(shí)例化
    print<int>(a, b);
    print<double>(a, b);
    
  • 其實(shí)還有一種改進(jìn)的方法,那就是增加模版參數(shù),因?yàn)橐粋€(gè)模版參數(shù)接收兩種類型是無法進(jìn)行自動(dòng)推導(dǎo)的,此時(shí)若是有兩個(gè)模版參數(shù)的話就可以接收兩種類型了,不會(huì)出現(xiàn)錯(cuò)誤感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)

三、類模版

講完了函數(shù)模版后,我們?cè)賮碚f說類模版,也就是對(duì)一個(gè)類來說,也是可以定義為一個(gè)模版的

1、類模板的定義格式

  • 首先來看到的就是其定義格式,函數(shù)模版加在函數(shù)上,那對(duì)于類模版的話就是加在類上
    template<class T1, class T2, ..., class Tn>
    class 類模板名
    {
     // 類內(nèi)成員定義
    };
    

    我們以下面這個(gè)Stack類為例來進(jìn)行講解

  • 如果你學(xué)習(xí)了模版的相關(guān)知識(shí)后,一定會(huì)覺得這個(gè)類的限制性太大了,只能初始化一個(gè)具有整型數(shù)據(jù)的棧,如果此時(shí)我想要放一些浮點(diǎn)型的數(shù)據(jù)進(jìn)來的話也做不到
    typedef int DataType;
    class Stack
    {
    public:
        Stack(size_t capacity = 3)
        {
            _array = (DataType*)malloc(sizeof(DataType) * capacity);
            if (NULL == _array)
            {
                perror("malloc申請(qǐng)空間失敗!!!");
                return;
            }
            _capacity = capacity;
            _size = 0;
        }
        void Push(DataType data)
        {
            // CheckCapacity();
            _array[_size] = data;
            _size++;
        }
        // 其他方法...
        ~Stack()
        {
            if (_array)
            {
                free(_array);
                _array = NULL;
                _capacity = 0;
                _size = 0;
    
            }
        }
    private:
        DataType* _array;
        int _capacity;
        int _size;
    };
    

    ?? 如果沒有模版技術(shù)的話你會(huì)如何去解決這個(gè)問題呢?很簡(jiǎn)單那就是定義多個(gè)類

  • ?這是我們同學(xué)最擅長(zhǎng)的事,CV一下兩個(gè)棧就有了,StackInt存放整型數(shù)據(jù),StackDouble存放浮點(diǎn)型數(shù)據(jù)

但是本文我們重點(diǎn)要講解的就是【模版技術(shù)】,技術(shù)界有一句話說得好 “不要重復(fù)造輪子

  • 下面就是使用模版去定義的一個(gè)類,簡(jiǎn)稱【模板類】,不限制死數(shù)據(jù)類型,將所有的DataType都改為【T】
    template<class T>
    class Stack
    {
    public:
        Stack(size_t capacity = 3)
        {
            _array = (DataType*)malloc(sizeof(DataType) * capacity);
            if (NULL == _array)
            {
                perror("malloc申請(qǐng)空間失敗!!!");
                return;
            }
            _capacity = capacity;
            _size = 0;
        }
        void Push(T data)
        {
            // CheckCapacity();
            _array[_size] = data;
            _size++;
        }
        // 其他方法...
        ~Stack()
        {
            if (_array)
            {
                free(_array);
                _array = NULL;
                _capacity = 0;
                _size = 0;
    
            }
        }
    private:
        T* _array;
        int _capacity;
        int _size;
    };
    
  • 但是呢就上面這樣其實(shí)并不是最規(guī)范的寫法,還記得我們?cè)趯W(xué)習(xí)C++類和對(duì)象講到過一個(gè)類要聲明和定義分離,那對(duì)于模板類也同樣適用,我們馬上來看看
    template<class T>		// 類模版
    class Stack
    {
    public:
    	Stack(size_t capacity = 3);
    	void Push(T data);
    	~Stack();
    private:
    	T* _array;
    	int _capacity;
    	int _size;
    };
    
  • 不過呢可以看到直接像我們之前那樣去進(jìn)行類外定義似乎行不通,說缺少類模版“Stack”的參數(shù)列表,因?yàn)檫@個(gè)成員函數(shù)內(nèi)部也使用到了模版參數(shù)T,那么這個(gè)函數(shù)也要變?yōu)楹瘮?shù)模版才行感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)
  • ?但是在加上這個(gè)模版參數(shù)后,似乎還是有問題,::這個(gè)操作符我們?cè)贑++命名空間中有提到過,叫做【域作用限定符】,是我們使用命名空間去訪問特定成員變量或成員函數(shù)時(shí)使用的,對(duì)于類來說它一定要是一個(gè)類名
  • 這里要強(qiáng)調(diào)一點(diǎn)的是對(duì)于普通類來說類名和類型是一樣的, 像構(gòu)造函數(shù),它的函數(shù)名就是類名;可是對(duì)于模板類來說是不一樣,類名和類型不一樣,這里Stack只是這個(gè)模版類的類名罷了,但我們現(xiàn)在需要的是類型,此處就想到了我們?cè)谏厦嫠鶎W(xué)的【顯式實(shí)例化】,這個(gè)模板類的類型即為Stack<T>感受C++模版的所帶來的魅力,java,算法,數(shù)據(jù)結(jié)構(gòu)
  • 以下即是對(duì)這個(gè)模版類中的成員函數(shù)在類外實(shí)現(xiàn)所需要變化成的模版函數(shù)
template<class T>
Stack<T>::Stack(size_t capacity)
{
	_array = new T(capacity);
	_capacity = capacity;
	_size = 0;
}
  • 那對(duì)于其他函數(shù)也是一致,均需要將它們定義為模版函數(shù),此時(shí)我們可以意識(shí)到一點(diǎn)的是對(duì)于模版函數(shù)來說,其模版參數(shù)的作用域就在這個(gè)函數(shù)內(nèi)部,出了這個(gè)函數(shù)就無法使用了, 所以可以看到每個(gè)函數(shù)前面都需要其對(duì)應(yīng)的模版參數(shù);而且對(duì)于模版類來說也是同理,只在這個(gè)類內(nèi)起作用,即到收括號(hào)};為止,我們知道對(duì)于一個(gè)類來說也算是一個(gè)獨(dú)立的空間,成員函數(shù)是不包含在類內(nèi)的,所以其在類外進(jìn)行定義的時(shí)候就需要再重新定義模版參數(shù)
    template<class T>		// 每個(gè)函數(shù)或類前都要加上其對(duì)應(yīng)的模版參數(shù)
    void Stack<T>::Push(T data)
    {
    	// CheckCapacity();
    	_array[_size] = data;
    	_size++;
    }
    
    template<class T>
    Stack<T>::~Stack()
    {
    	if (_array)
    	{
    		free(_array);
    		_array = NULL;
    		_capacity = 0;
    		_size = 0;
    	}
    }
    

    2、類模板的實(shí)例化

清楚了什么是類模版之后,我們就將上面的這個(gè)Stack類模版給實(shí)例化出來吧

?? 類模板實(shí)例化與函數(shù)模板實(shí)例化不同,類模板實(shí)例化需要在類模板名字后跟<>,然后將實(shí)例化的類型放在<>中即可,類模板名字不是真正的類,而實(shí)例化的結(jié)果才是真正的類

  • 可以看到因?yàn)槲覀儗⑦@個(gè)類定義為了類模版,此時(shí)便可以去初始化不同數(shù)據(jù)類型的棧了,上面說到過Stack是類名,但是像Stack<int>、Stack<double>這些都是它的類型
    int main(void)
    {
    	Stack<int> s1;		// int
    	Stack<double> s2;	// double
    	Stack<char> s3;		// char
    	return 0;
    }
    

    四、總結(jié)與提煉

最后我們來總結(jié)一下本文所學(xué)習(xí)的內(nèi)容??

  • 首先我們了解了什么是泛型編程的思想,通過曹植的《洛神賦》到【活字印刷術(shù)】,我們體會(huì)到了有一個(gè)通用模版的重要性,于是就引申出了C++中的模版這一個(gè)概念,對(duì)于模版呢,其分為 函數(shù)模版 和 類模版
  • 首先呢我們介紹了什么是【函數(shù)模版】,新學(xué)習(xí)了一個(gè)關(guān)鍵字叫做template,用它再配合模版參數(shù)就可以去定義出一個(gè)函數(shù)模版,有了它,我們?cè)趯懸恍┫嗤愋秃瘮?shù)的時(shí)候就無需去進(jìn)行重復(fù)的CV操作了,在通過匯編觀察函數(shù)模版的原理后,清楚了我們只需要傳入不同的類型,此時(shí)模版參數(shù)就會(huì)去進(jìn)行一個(gè)自動(dòng)類型推導(dǎo),從而產(chǎn)生不同的函數(shù)。函數(shù)模版定義好后還要對(duì)其實(shí)例化才能繼續(xù)使用,但此時(shí)要注意的一點(diǎn)是如果傳遞進(jìn)去的類型個(gè)數(shù)與模版參數(shù)的個(gè)數(shù)不匹配的話,其就無法完成自動(dòng)類型推導(dǎo),因?yàn)檫@會(huì)產(chǎn)生一個(gè)歧義。所以想要真正學(xué)好模版,這點(diǎn)是一定要搞清楚的?。?!
  • 接下去呢我們又學(xué)習(xí)了【類模版】,沒想到吧,類也可以變成一個(gè)模版,以Stack類為例,對(duì)于類模版而言,其類名和類型與普通類是不一樣的,這點(diǎn)要注意了,尤其體現(xiàn)在類的成員函數(shù)放在類外進(jìn)行定義的時(shí)候,也要將其定義為函數(shù)模版,函數(shù)名前面指明其類型,這才不會(huì)出問題。有了類模版之后,我們?nèi)ワ@式實(shí)例化不同的數(shù)據(jù)類型后也可以讓模版參數(shù)去做一個(gè)自動(dòng)類型推導(dǎo)從而得到不同數(shù)據(jù)類型的棧

?總而言之,模版是C++的一個(gè)亮點(diǎn)所在,也是學(xué)習(xí)STL的基礎(chǔ),望讀者扎實(shí)掌握??


以上就是本文要介紹的所有內(nèi)容,感謝您的閱讀??

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

此文借鑒與https://blog.csdn.net/Fire_Cloud_1/article/details/131611593文章來源地址http://www.zghlxwxcb.cn/news/detail-555090.html

到了這里,關(guān)于感受C++模版的所帶來的魅力的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 龍蜥社區(qū)「人人都可以參與開源」—— 走進(jìn)“龍蜥社區(qū)”感受開源魅力

    龍蜥社區(qū)「人人都可以參與開源」—— 走進(jìn)“龍蜥社區(qū)”感受開源魅力

    ?? 鴿芷咕 :個(gè)人主頁 ??? 個(gè)人專欄 : 《linux深造日志》《粉絲福利》 ??生活的理想,就是為了理想的生活! ?? 開源這個(gè)我相信各位開發(fā)者們或多或少都聽說過,簡(jiǎn)單來講開源就是源碼開放,但是不意味著使用沒有限制,具體規(guī)定要根據(jù)軟件的開源協(xié)議來決定。

    2024年04月11日
    瀏覽(21)
  • 5款A(yù)I應(yīng)用讓你全面感受人工智能的魅力

    5款A(yù)I應(yīng)用讓你全面感受人工智能的魅力

    ????????????????????????????????“ ?AI 的出現(xiàn)就像燃?xì)鈾C(jī)和蒸汽機(jī)一樣,極大地提高了生產(chǎn)力。” ????????????????????????????????????????????????????????????????chatGPT ChatGPT 是由 OpenAI 公司開發(fā)的一種大型語言模型。 OpenAI 公

    2024年02月08日
    瀏覽(51)
  • 低代碼平臺(tái)活字格,讓我們一起感受低代碼平臺(tái)活字格的魅力

    一份耕耘,一份收獲,一段工作經(jīng)歷,讓我認(rèn)識(shí)了活字格。感覺活字格絕對(duì)是同類產(chǎn)品中的佼佼者。簡(jiǎn)單的拖拉拽,就實(shí)現(xiàn)一個(gè)完美的WEB頁面,并且可做到前后端分離與交互。有了他,不擅長(zhǎng)前端的我,也能大顯身手了。告別VUE,我選活字格。用它做原型,絕對(duì)勝過Axure ,用它來

    2024年02月06日
    瀏覽(20)
  • 探索設(shè)計(jì)模式的魅力:“感受單例模式的力量與神秘” - 掌握編程的王牌技巧

    探索設(shè)計(jì)模式的魅力:“感受單例模式的力量與神秘” - 掌握編程的王牌技巧

    ? ? ? 在軟件開發(fā)的賽場(chǎng)上,單例模式以其獨(dú)特的魅力長(zhǎng)期占據(jù)著重要的地位。作為設(shè)計(jì)模式中的一員,它在整個(gè)軟件工程的棋盤上扮演著關(guān)鍵性角色。本文將帶你深入探索單例模式的神秘面紗,從歷史淵源到現(xiàn)代應(yīng)用,從基礎(chǔ)實(shí)現(xiàn)到高級(jí)技巧,經(jīng)過戲劇性的轉(zhuǎn)折和層層推進(jìn)

    2024年01月20日
    瀏覽(22)
  • 【C++】數(shù)據(jù)結(jié)構(gòu)與算法:常用排序算法

    【C++】數(shù)據(jù)結(jié)構(gòu)與算法:常用排序算法

    ?? ★,° :.☆( ̄▽ ̄)/$: .°★ ?? 這篇文章主要介紹常用排序算法。 學(xué)其所用,用其所學(xué)?!?jiǎn)⒊?歡迎來到我的博客,一起學(xué)習(xí),共同進(jìn)步。 喜歡的朋友可以關(guān)注一下,下次更新不迷路?? 排序算法是計(jì)算機(jī)科學(xué)中常見的一類算法,用于將一組數(shù)據(jù)按照特定的順序進(jìn)行排

    2024年02月14日
    瀏覽(25)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法C++實(shí)現(xiàn)】3、排序算法

    【數(shù)據(jù)結(jié)構(gòu)與算法C++實(shí)現(xiàn)】3、排序算法

    原視頻為左程云的B站教學(xué) 外層循環(huán) :n個(gè)數(shù)需要冒n-1個(gè)泡上去,剩下的一個(gè)必然是最小的。所以外層循環(huán)執(zhí)行n-1輪 內(nèi)層循環(huán) :比大小,第1個(gè)泡需要比n-1次,第2個(gè)泡,比較n-2次… 選擇: 每次從待排序序列中選擇 最小的一個(gè) 放在已排序序列的后一個(gè)位置 原理類似于對(duì)撲克牌

    2024年02月11日
    瀏覽(23)
  • C++數(shù)據(jù)結(jié)構(gòu)與算法——哈希表

    C++數(shù)據(jù)結(jié)構(gòu)與算法——哈希表

    C++第二階段——數(shù)據(jù)結(jié)構(gòu)和算法,之前學(xué)過一點(diǎn)點(diǎn)數(shù)據(jù)結(jié)構(gòu),當(dāng)時(shí)是基于Python來學(xué)習(xí)的,現(xiàn)在基于C++查漏補(bǔ)缺,尤其是樹的部分。這一部分計(jì)劃一個(gè)月,主要利用代碼隨想錄來學(xué)習(xí),刷題使用力扣網(wǎng)站,不定時(shí)更新,歡迎關(guān)注! 給定兩個(gè)字符串 s 和 t ,編寫一個(gè)函數(shù)來判斷

    2024年02月19日
    瀏覽(38)
  • C++基礎(chǔ)-介紹·數(shù)據(jù)結(jié)構(gòu)·排序·算法

    C++是一門風(fēng)格嚴(yán)謹(jǐn)又不失自由的開發(fā)語言,提供了完整的內(nèi)存管理、支持函數(shù)式編程和面向?qū)ο缶幊?,支持模板、多繼承、多實(shí)現(xiàn)、重載、重寫等多態(tài)特性。 優(yōu)勢(shì)在于目前90%的操作系統(tǒng)、數(shù)據(jù)庫、應(yīng)用基礎(chǔ)架構(gòu)、硬件嵌入式等都是使用C/C++制作的,而C++是對(duì)C的標(biāo)準(zhǔn)擴(kuò)展,掌握

    2024年02月03日
    瀏覽(33)
  • 鏈表綜合算法設(shè)計(jì)(c++數(shù)據(jù)結(jié)構(gòu))

    ? 一、設(shè)計(jì)內(nèi)容 已知簡(jiǎn)單的人事信息系統(tǒng)中職工記錄包含職工編號(hào)(no)、職工姓名(name)、部門名稱(depname)、職稱(title)和工資數(shù)(salary)等信息(可以增加其他信息),設(shè)計(jì)并完成一個(gè)簡(jiǎn)單的人事信息管理系統(tǒng),要求完成但不限于以下功能: (1)?? ?增加一個(gè)職工信息

    2024年02月02日
    瀏覽(33)
  • C++數(shù)據(jù)結(jié)構(gòu)與算法——棧與隊(duì)列

    C++數(shù)據(jù)結(jié)構(gòu)與算法——棧與隊(duì)列

    C++第二階段——數(shù)據(jù)結(jié)構(gòu)和算法,之前學(xué)過一點(diǎn)點(diǎn)數(shù)據(jù)結(jié)構(gòu),當(dāng)時(shí)是基于Python來學(xué)習(xí)的,現(xiàn)在基于C++查漏補(bǔ)缺,尤其是樹的部分。這一部分計(jì)劃一個(gè)月,主要利用代碼隨想錄來學(xué)習(xí),刷題使用力扣網(wǎng)站,不定時(shí)更新,歡迎關(guān)注! 請(qǐng)你僅使用兩個(gè)棧實(shí)現(xiàn)先入先出隊(duì)列。隊(duì)列應(yīng)當(dāng)

    2024年02月20日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包