摘要:文章目錄模板模板的概念函數(shù)模板函數(shù)模板語(yǔ)法函數(shù)模板注意事項(xiàng)函數(shù)模板案例普通函數(shù)與函數(shù)模板的區(qū)別普通函數(shù)與函數(shù)模板的調(diào)用規(guī)則模板的局限性類模板類模板語(yǔ)法類模板與函數(shù)模板區(qū)別類模板中成員函數(shù)創(chuàng)建時(shí)機(jī)類模板對(duì)象做函數(shù)參數(shù)類模
本階段主要針對(duì)C++泛型編程和STL技術(shù)做詳細(xì)講解,探討C++更深層的使用
模板就是建立通用的模具,大大提高復(fù)用性
模板的特點(diǎn):
函數(shù)模板作用:建立一個(gè)通用函數(shù),其函數(shù)返回值類型和形參類型可以不具體制定,用一個(gè)虛擬的類型來(lái)代表。
語(yǔ)法:
template<typename T>函數(shù)聲明或定義
解釋:
#include using namespace std;//函數(shù)模板//兩個(gè)整型交換函數(shù)void swapInt(int &a, int &b) { int temp = a; a = b; b = temp;}//交換兩個(gè)浮點(diǎn)型函數(shù)void swapDouble(double& a, double& b) { double temp = a; a = b; b = temp;}//函數(shù)模板template<typename T> //聲明一個(gè)模板,告訴編譯器后面代碼中緊跟著的T不要報(bào)錯(cuò),T是一個(gè)通用數(shù)據(jù)類型void mySwap(T& a, T& b) { T temp = a; a = b; b = temp;}void test01() { float a = 10; float b = 20; //兩種方式使用函數(shù)模板 //1、自動(dòng)類型推導(dǎo) mySwap(a, b); cout << "a:" << a << endl; cout << "b:" << b << endl; cout << "/n"; //2、顯示指定類型 mySwap<float>(a, b); cout << "a:" << a << endl; cout << "b:" << b << endl;}int main() { test01(); system("pause"); system("cls");}
總結(jié):
注意事項(xiàng):
//利用模板提供通用的交換函數(shù)template<class T>void mySwap(T& a, T& b){ T temp = a; a = b; b = temp;}// 1、自動(dòng)類型推導(dǎo),必須推導(dǎo)出一致的數(shù)據(jù)類型T,才可以使用void test01(){ int a = 10; int b = 20; char c = "c"; mySwap(a, b); // 正確,可以推導(dǎo)出一致的T //mySwap(a, c); // 錯(cuò)誤,推導(dǎo)不出一致的T類型}// 2、模板必須要確定出T的數(shù)據(jù)類型,才可以使用template<class T>void func(){ cout << "func 調(diào)用" << endl;}void test02(){ //func(); //錯(cuò)誤,模板不能獨(dú)立使用,必須確定出T的類型 func<int>(); //利用顯示指定類型的方式,給T一個(gè)類型,才可以使用該模板}int main() { test01(); test02(); system("pause"); return 0;}
總結(jié):使用模板時(shí)必須確定出通用數(shù)據(jù)類型T,并且能夠推導(dǎo)出一致的類型
案例描述:
利用函數(shù)模板封裝一個(gè)排序的函數(shù),可以對(duì)不同數(shù)據(jù)類型數(shù)組進(jìn)行排序
排序規(guī)則從大到小,排序算法為選擇排序
分別利用char數(shù)組和int數(shù)組進(jìn)行測(cè)試
#include using namespace std;//實(shí)現(xiàn)通用 對(duì)數(shù)組進(jìn)行排序的函數(shù)//從大到小 選擇排序//測(cè)試 char數(shù)組、 int數(shù)組//交換函數(shù)模板template<class T>void mySwap(T& a, T& b) { T temp = a; a = b; b = temp;}//排序算法:選擇排序,每次選擇最大的一個(gè)放在前面template<class T>void mySort(T arr[], int len) { for (int i = 0; i < len; i++) { int max = i; //認(rèn)定最大值的下標(biāo) for (int j = i + 1; j < len; j++) { if (arr[max] < arr[j]) { max = j; } } if (max != i) { //交換max和i元素 mySwap(arr[max], arr[i]); } }}//提供打印數(shù)組模板template<class T>void printArray(T arr[], int len) { for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout << endl;}void test01() { //測(cè)試char數(shù)組 char charArr[] = "badcfe"; int num = sizeof(charArr) / sizeof(char); mySort(charArr, num); printArray(charArr, num);}void test02() { //測(cè)試int數(shù)組 int intArr[] = { 7,5,1,3,9,2,4,6,8 }; int num = sizeof(intArr) / sizeof(int); mySort(intArr, num); printArray(intArr, num);}int main() { test01(); test02(); system("pause"); system("cls");}
f e d c b a9 8 7 6 5 4 3 2 1請(qǐng)按任意鍵繼續(xù). . .
普通函數(shù)與函數(shù)模板區(qū)別:
#include using namespace std;//普通函數(shù)和函數(shù)模板的區(qū)別//1、普通函數(shù)調(diào)用可以發(fā)生隱式類型轉(zhuǎn)換//2、函數(shù)模板 用自動(dòng)類型推導(dǎo),不可以發(fā)生隱式類型轉(zhuǎn)換//3、函數(shù)模板 用顯示指定類型,可以發(fā)生隱式類型轉(zhuǎn)換//普通函數(shù)int myAdd01(int a, int b) { return a + b;}//函數(shù)模板template<class T>T myAdd02(T a, T b) { return a + b;}void test01() { int a = 10; int b = 20; char c = "c"; //99 //cout << myAdd01(a, b) << endl; cout << myAdd01(a, c) << endl; //1、自動(dòng)類型推導(dǎo) 不會(huì)發(fā)生隱式類型轉(zhuǎn)換 //cout << myAdd02(a, c) << endl; //報(bào)錯(cuò),無(wú)法推導(dǎo)出一致的T //2、顯示指定類型 會(huì)發(fā)生隱式類型轉(zhuǎn)換 cout << myAdd02<int>(a, c) << endl; cout << myAdd02<char>(a, c) << endl;}int main() { test01(); system("pause"); system("cls");}
總結(jié):建議使用顯示指定類型的方式,調(diào)用函數(shù)模板,因?yàn)榭梢宰约捍_定通用類型T
調(diào)用規(guī)則如下:
#include using namespace std;//普通函數(shù)與函數(shù)模板的調(diào)用規(guī)則//1、如果函數(shù)模板和普通函數(shù)都可以調(diào)用,優(yōu)先調(diào)用普通函數(shù)//2、可以通過(guò)空模板參數(shù)列表 強(qiáng)制調(diào)用 函數(shù)模板//3、函數(shù)模板可以發(fā)生函數(shù)重載//4、如果函數(shù)模板可以產(chǎn)生更好的匹配,優(yōu)先調(diào)用函數(shù)模板void myPrint(int a, int b){ cout << "調(diào)用的普通函數(shù)" << endl;}template<class T>void myPrint(T a, T b) { cout << "調(diào)用的模板" << endl;}template<class T>void myPrint(T a, T b, T c) { cout << "調(diào)用重載的模板" << endl;}void test01() { int a = 10; int b = 20; myPrint(a, b); //調(diào)用的普通函數(shù) //通過(guò)空模板參數(shù)列表,強(qiáng)制調(diào)用函數(shù)模板 myPrint<>(a, b); //調(diào)用模板 myPrint<>(a, b, 100); //調(diào)用重載的模板 //如果函數(shù)模板可以產(chǎn)生更好的匹配,優(yōu)先調(diào)用函數(shù)模板 char c1 = "a"; char c2 = "b"; myPrint(c1, c2); //調(diào)用模板}int main() { test01(); system("pause"); system("cls");}
調(diào)用的普通函數(shù)調(diào)用的模板調(diào)用重載的模板調(diào)用的模板請(qǐng)按任意鍵繼續(xù). . .
總結(jié):既然提供了函數(shù)模板,最好就不要提供普通函數(shù),否則容易出現(xiàn)二義性
局限性:模板的通用性并不是萬(wàn)能的
template<class T> void f(T a, T b) { a = b; }
在上述代碼中提供的賦值操作,如果傳入的a和b是一個(gè)數(shù)組,就無(wú)法實(shí)現(xiàn)了
template<class T> void f(T a, T b) { if(a > b) { ... } }
在上述代碼中,如果T的數(shù)據(jù)類型傳入的是像Person這樣的自定義數(shù)據(jù)類型,也無(wú)法正常運(yùn)行
因此C++為了解決這種問(wèn)題,提供模板的重載,可以為這些特定的類型提供具體化的模板
#include using namespace std;//模板局限性//特定數(shù)據(jù)類型 需要用具體方式做特殊實(shí)現(xiàn)class Person {public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } //姓名 string m_Name; //年齡 string m_Age;};//對(duì)比兩個(gè)數(shù)據(jù)是否相等函數(shù)template<class T>bool myCompare(T& a, T& b) { if (a == b) { return true; } else { return false; }}//利用具體化Person的版本實(shí)現(xiàn)代碼,具體化優(yōu)先調(diào)用template<> bool myCompare(Person& p1, Person& p2) { if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age) { return true; } else { return false; }}void test01() { int a = 10; int b = 20; bool ret = myCompare(a, b); if (ret) { cout << "a == b" << endl; } else { cout << "a != b" << endl; }}void test02() { Person p1("Tom", 10); Person p2("Tom", 10); bool ret = myCompare(p1, p2); if (ret) { cout << "p1 == p2" << endl; } else { cout << "p1 != p2" << endl; }}int main() { test01(); test02(); system("pause"); system("cls");}
總結(jié):
類模板作用:建立一個(gè)通用類,類中的成員 數(shù)據(jù)類型可以不具體制定,用一個(gè)虛擬的類型來(lái)代表。
語(yǔ)法:
template<typename T>類
解釋:
#include using namespace std;//類模板template<class NameType, class AgeType>class Person {public: Person(NameType name, AgeType age) { this->m_Name = name; this->m_Age = age; } void showPerson() { cout << "name:" << this->m_Name << endl; cout << "age:" << this->m_Age << endl; } NameType m_Name; AgeType m_Age;};void test01() { Person<string, int> p1("張三", 18); cout << p1.m_Name << "," << p1.m_Age << endl; p1.showPerson();}int main() { test01(); system("pause"); system("cls");}
張三,18name:張三age:18請(qǐng)按任意鍵繼續(xù). . .
總結(jié):類模板和函數(shù)模板語(yǔ)法相似,在聲明模板template后面加類,此類稱為類模板
類模板與函數(shù)模板區(qū)別主要有兩點(diǎn):
#include using namespace std;//類模板和函數(shù)模板區(qū)別template<class NameType, class AgeType = int>class Person {public: Person(NameType name, AgeType age) { this->m_Name = name; this->m_Age = age; } void showPerson() { cout << "name:" << this->m_Name << endl; cout << "age:" << this->m_Age << endl; } NameType m_Name; AgeType m_Age;};void test01() { //Person p("張三", 18); //1、類模板沒(méi)有自動(dòng)類型推導(dǎo)使用方式 Person<string, int> p("張三", 18); p.showPerson();}//2、類模板在模板參數(shù)列表中可以有默認(rèn)參數(shù)void test02() { Person<string> p2("李四", 20); //后一個(gè)參數(shù)默認(rèn)整型, 默認(rèn)參數(shù)只有類模板有,函數(shù)模板沒(méi)有 p2.showPerson();}int main() { test01(); test02(); system("pause"); system("cls");}
name:張三age:18name:李四age:20請(qǐng)按任意鍵繼續(xù). . .
總結(jié):
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/122421.html
摘要:只讀目的是防止程序意外地修改了它的指令。全局區(qū)存放全局變量靜態(tài)變量和常量除了修飾的局部變量。程序結(jié)束時(shí)由操作系統(tǒng)釋放。由編譯器自動(dòng)分配和釋放。注意不要返回局部變量的地址。 ...
摘要:本書主要圍繞一系列逐漸復(fù)雜的程序問(wèn)題,以及用以解決這些問(wèn)題的語(yǔ)言特性展開(kāi)講解。你不只學(xué)到的函數(shù)和結(jié)構(gòu),也會(huì)學(xué)習(xí)到它們的設(shè)計(jì)目的和基本原理。因此我們把精力集中在最有價(jià)值的地方。本書不僅是對(duì)模板的權(quán)威解釋,而且本書還深入地介紹了其他一般的思想。 C++ 入門教程(41課時(shí)) - 阿里云大學(xué) C+...
摘要:與都繼承自類,在中也是使用字符數(shù)組保存字符串,,這兩種對(duì)象都是可變的。采用字節(jié)碼的好處語(yǔ)言通過(guò)字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語(yǔ)言執(zhí)行效率低的問(wèn)題,同時(shí)又保留了解釋型語(yǔ)言可移植的特點(diǎn)。 String和StringBuffer、StringBuilder的區(qū)別是什么?String為什么是不可變的? String和StringBuffer、StringBuilder的區(qū)別 可變性...
摘要:目前,中關(guān)村黑馬程序員訓(xùn)練營(yíng)已成長(zhǎng)為行業(yè)學(xué)員質(zhì)量好課程內(nèi)容深企業(yè)滿意的移動(dòng)開(kāi)發(fā)高端訓(xùn)練基地,并被評(píng)為中關(guān)村軟件園重點(diǎn)扶持人才企業(yè)。黑馬程序員的學(xué)員篩選制度,遠(yuǎn)比現(xiàn)在以上的企業(yè)招聘流程更為嚴(yán)格。系統(tǒng)的學(xué)習(xí)可以參考w3c的教程 web概念概述 * JavaWeb: * 使用Java語(yǔ)言開(kāi)發(fā)基于互聯(lián)網(wǎng)的項(xiàng)目 * 軟件架構(gòu): 1. C/S: Client/Server 客戶端/服務(wù)...
摘要:而面向搜索引擎,就是我們要及時(shí)的使用百度谷歌遇到問(wèn)題無(wú)法解決,先別急著放棄,可以去網(wǎng)絡(luò)尋找答案,你的坑大部分別人都已經(jīng)走過(guò)了,大部分都可以找到合適的解決方案。 showImg(https://segmentfault.com/img/remote/1460000019236352?w=866&h=456); 前言: ●眾多的語(yǔ)言,到底哪一門才是適合我的?●我們?yōu)槭裁匆獙W(xué)習(xí)Java語(yǔ)言呢...
閱讀 2478·2021-11-23 09:51
閱讀 1880·2021-10-13 09:40
閱讀 1402·2021-09-30 10:01
閱讀 605·2021-09-26 09:46
閱讀 2264·2021-09-23 11:55
閱讀 1421·2021-09-10 10:51
閱讀 2281·2021-09-09 09:33
閱讀 2243·2019-08-29 17:25