C++之泛型編程-創(chuàng)新互聯(lián)

目錄

創(chuàng)新互聯(lián)秉承實(shí)現(xiàn)全網(wǎng)價(jià)值營(yíng)銷的理念,以專業(yè)定制企業(yè)官網(wǎng),成都網(wǎng)站建設(shè)、做網(wǎng)站,小程序開發(fā),網(wǎng)頁設(shè)計(jì)制作,移動(dòng)網(wǎng)站建設(shè),營(yíng)銷型網(wǎng)站建設(shè)幫助傳統(tǒng)企業(yè)實(shí)現(xiàn)“互聯(lián)網(wǎng)+”轉(zhuǎn)型升級(jí)專業(yè)定制企業(yè)官網(wǎng),公司注重人才、技術(shù)和管理,匯聚了一批優(yōu)秀的互聯(lián)網(wǎng)技術(shù)人才,對(duì)客戶都以感恩的心態(tài)奉獻(xiàn)自己的專業(yè)和所長(zhǎng)。

模板

模板的特點(diǎn)

函數(shù)模板

前言

函數(shù)模板的使用方式

函數(shù)模板具體案例

使用模板的注意事項(xiàng)

普通函數(shù)與函數(shù)模板間的區(qū)別

具體案例

普通函數(shù)與函數(shù)模板調(diào)用規(guī)則

模板的局限性

具體化模板

類模板

前言

類模板與函數(shù)模板的區(qū)別

類模板中成員函數(shù)創(chuàng)建時(shí)機(jī)

類模板對(duì)象做函數(shù)的參數(shù)

傳入方式

具體案例

類模板與繼承

前言

子類指定具體類型案例

子類不指定具體類型案例

類模板成員函數(shù)的類外實(shí)現(xiàn)

類模板分文件編寫

1.直接包含源文件

2.將.h和.cpp文件中的內(nèi)容寫到一起,后將后綴名改為.hpp文件

類模板與友元

模板

前言:

  • C++中相對(duì)于面向?qū)ο蟮牧硪环N編程思想就是泛型編程,主要利用的技術(shù)就是模板
  • C++提供了兩種模板機(jī)制(函數(shù)模板和類模板)

概念:模板就是建立通用的模具,大大提高復(fù)用性

模板的特點(diǎn)
  • 模板不可以直接使用,它只是一個(gè)框架
  • 模板通用性很強(qiáng),但是并不是萬能的

使用模板的目的:提高復(fù)用性,將類型參數(shù)化?

函數(shù)模板 前言

作用:建立一個(gè)通用函數(shù),其函數(shù)返回值類型和形參類型可以不具體制定,用一個(gè)虛擬的類型來代表

語法:

//聲明一個(gè)模板,告訴編譯器后面代碼中緊跟著的T不要報(bào)錯(cuò),T是一個(gè)通用的數(shù)據(jù)類型
template函數(shù)聲明或函數(shù)定義

解釋:

  • template:聲明創(chuàng)建模板
  • typename:表明其后面的符號(hào)為一種數(shù)據(jù)類型(該關(guān)鍵字也可以用class代替)
  • T:通用的數(shù)據(jù)類型;名稱可以替換,通常為大寫字母。
函數(shù)模板的使用方式
  • 自動(dòng)類型推導(dǎo):向交換模板函數(shù)中傳遞的參數(shù)的類型會(huì)被自動(dòng)解析
  • 顯示指定類型:指定模板的具體數(shù)據(jù)類型
函數(shù)模板具體案例
#define _CRT_SECURE_NO_WARNINGS 1
#includeusing namespace std;
//函數(shù)模板
template//通用交換函數(shù)模板
void mySwap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}
void main() {
	int a = 10;
	int b = 20.0;
	//自動(dòng)類型推導(dǎo)(a和b的數(shù)據(jù)類型會(huì)被自動(dòng)解析)
	mySwap(a, b);
	cout<< "a:"<< a<< "\tb:"<< b<< endl;
	//顯式指定類型(為模板參數(shù))
	mySwap(a,b);
	cout<< "a:"<< a<< "\tb:"<< b<< endl;
}
使用模板的注意事項(xiàng)
  • 在函數(shù)中,若多個(gè)參數(shù)使用模板,那么自動(dòng)類型推導(dǎo)必須推導(dǎo)出一致的數(shù)據(jù)類型才可以使用
  • 模板必須確定出T的數(shù)據(jù)類型才可以使用
普通函數(shù)與函數(shù)模板間的區(qū)別

普通函數(shù)調(diào)用時(shí)可以發(fā)生自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換);函數(shù)模板調(diào)用時(shí),若利用自動(dòng)類型推導(dǎo),則不會(huì)發(fā)生隱式類型轉(zhuǎn)換,但若利用顯式指定類型的方式則可以發(fā)生隱式類型轉(zhuǎn)換

具體案例
#includeusing namespace std;
templateT myAdd(T a, T b) {
	return a + b;
}
void main() {
	int a = 10;
	char c = 'c';
	//自動(dòng)類型推導(dǎo)
	//cout<< myAdd(a, c)<< endl;//報(bào)錯(cuò),參數(shù)類型的指定必須一致,不能自動(dòng)類型轉(zhuǎn)換
	//隱式指定類型
	cout<< myAdd(a, c)<< endl;
	//明確說明T的類型為int,傳入的參數(shù)是int類型直接傳,不是int類型則使用隱式類型轉(zhuǎn)換轉(zhuǎn)為int類型
}
普通函數(shù)與函數(shù)模板調(diào)用規(guī)則

1.若函數(shù)模板與普通函數(shù)都可以調(diào)用,則優(yōu)先調(diào)用普通函數(shù)

void myPrint(int a, int b) {
	cout<< "調(diào)用普通函數(shù)"<< endl;
}
templatevoid myPrint(T a, T b) {
	cout<< "調(diào)用函數(shù)模板"<< endl;
}
void main() {
	int a = 10;
	int b = 20;
	myPrint(a, b);//調(diào)用普通函數(shù)
}

2.可以通過空模板參數(shù)列表的方式來強(qiáng)制調(diào)用函數(shù)模板

//只寫了函數(shù)聲明,沒寫函數(shù)實(shí)現(xiàn)
void myPrint(int a, int b);
templatevoid myPrint(T a, T b) {
	cout<< "調(diào)用函數(shù)模板"<< endl;
}
void main() {
	int a = 10;
	int b = 20;
	//通過空模板的參數(shù)列表強(qiáng)制調(diào)用函數(shù)模板
	myPrint<>(a, b);
}

3.模板也可以實(shí)現(xiàn)函數(shù)重載

templatevoid myPrint(T a, T b) {
	cout<< "調(diào)用函數(shù)模板1"<< endl;
}
//重載函數(shù)模板
templatevoid myPrint(T a, T b, T c) {
	cout<< "調(diào)用函數(shù)模板2"<< endl;
}
void main() {
	int a = 10;
	int b = 20;
	int c = 30;
	//調(diào)用函數(shù)模板1
	myPrint(a, b);
	//調(diào)用函數(shù)模板2
	myPrint(a, b, c);
}

4.如果函數(shù)模板可以產(chǎn)生更好的匹配,則優(yōu)先使用函數(shù)模板

void myPrint(int a, int b) {
	cout<< "調(diào)用普通函數(shù)"<< endl;
}
templatevoid myPrint(T a, T b) {
	cout<< "調(diào)用函數(shù)模板"<< endl;
}
void main() {
	char a = 'a';
	char b = 'b';
	//調(diào)用函數(shù)模板
	myPrint(a, b);
}

注意:若提供了函數(shù)模板,那么最好就不要提供普通函數(shù),否則容易出現(xiàn)二義性

模板的局限性
templatevoid func(T a, T b) {
	a = b;
}

注意:模板并不是萬能的,該模板函數(shù)有一個(gè)局限性,若傳入的a和b是一個(gè)數(shù)組,那么就無法實(shí)現(xiàn)了

具體化模板
class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};
templatebool myCompare(T& a, T& b) {
	if (a == b) {
		return true;
	}
	else {
		return false;
	}
}
//利用具體化(template<>)的Person版本來實(shí)現(xiàn)代碼,具體化優(yōu)先調(diào)用
template<>bool myCompare(Person & a, Person & b) {
	if (a.m_Age == b.m_Age && a.m_Name == b.m_Name) {
		return true;
	}
	else {
		return false;
	}
}
void main() {
	Person p1("Tom", 10);
	Person p2("Tom", 10);
	bool ret = myCompare(p1, p2);
	if (ret) {
		cout<< "p1==p2"<< endl;
	}
	else {
		cout<< "p1!=p2"<< endl;
	}
}

解釋:模板的類型若為Person類型,那么自動(dòng)調(diào)用具體化了的方法?

類模板 前言

作用:建立一個(gè)通用的類,類中的成員,數(shù)據(jù)類型可以不具體指定,用一個(gè)虛擬的類型來代表

語法:?

template

解釋:

  • template:聲明創(chuàng)建模板
  • typename:表明其后面帶符號(hào)的是一種數(shù)據(jù)類型(也可以用class替換)
  • T:通用的數(shù)據(jù)類型,名稱可以替換,通常為大寫字母
類模板與函數(shù)模板的區(qū)別

1.類模板沒有自動(dòng)類型推導(dǎo)的使用方式

templateclass Person {
public:
	Person(NameType name, AgeType age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeType m_Age;
};
void main() {
	//類模板的使用(顯式指定類型)
	Personp("葉秋", 25);
	cout<< "p的name:"<< p.m_Name<< endl<< "p的age:"<< p.m_Age<< endl;
}

2.類模板在模板參數(shù)列表中可以有默認(rèn)參數(shù)

//int為類模板的默認(rèn)參數(shù)
templateclass Person {
public:
	Person(NameType name, AgeType age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeType m_Age;
};
void main() {
	//類模板默認(rèn)參數(shù)的使用
	Personp("葉秋", 25);
	cout<< "p的name:"<< p.m_Name<< endl<< "p的age:"<< p.m_Age<< endl;
}
類模板中成員函數(shù)創(chuàng)建時(shí)機(jī)
  • 普通類中的成員函數(shù)一開始就可以創(chuàng)建
  • 類模板中的成員函數(shù)在調(diào)用時(shí)才可以創(chuàng)建
類模板對(duì)象做函數(shù)的參數(shù) 傳入方式
  • 指定傳入類型——直接顯示對(duì)象的數(shù)據(jù)類型
  • 參數(shù)模板化——將對(duì)象中的參數(shù)變?yōu)槟0暹M(jìn)行傳遞
  • 整個(gè)類模板化——將這個(gè)對(duì)象類型模板化進(jìn)行傳遞
具體案例
templateclass Person {
public:
	Person(NameType name, AgeType age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	void showPerson() {
		cout<< "姓名:"<< this->m_Name<< "\t年齡:"<< this->m_Age<< endl;
	}
	NameType m_Name;
	AgeType m_Age;
};
//指定傳入類型
void printPerson1(Person&p) {
	p.showPerson();
}
//參數(shù)模板化
templatevoid printPerson2(Person&p) {
	p.showPerson();
}
//整個(gè)類模板化
templatevoid printPerson3(P &p) {
	p.showPerson();
}
void main() {
	Personp("孫悟空", 100);
	printPerson1(p);
	printPerson2(p);
	printPerson3(p);
}
類模板與繼承 前言
  • 當(dāng)子類繼承的父類是一個(gè)類模板時(shí),子類在聲明的時(shí)候需要指定父類的類型
  • 若不指定具體的類型,那么編譯器無法給予子類分配內(nèi)存
  • 若想靈活指定父類中T的類型,子類也需要變成類模板
子類指定具體類型案例
templateclass Base {
	T m;
};
class Son:public Base{};
子類不指定具體類型案例
templateclass Base {
	T m;
};
templateclass Son:public Base{};
類模板成員函數(shù)的類外實(shí)現(xiàn)
templateclass Person {
public:
	Person(NameType name, AgeType age);
	void showPerson();
	NameType m_Name;
	AgeType m_Age;
};
//構(gòu)造函數(shù)的類外實(shí)現(xiàn)
templatePerson::Person(NameType name,AgeType age){
	this->m_Name = name;
	this->m_Age = age;
}
//成員函數(shù)的類外實(shí)現(xiàn)
templatevoid Person::showPerson() {
	cout<< "姓名:"<< this->m_Name<< "\t年齡:"<< this->m_Age<< endl;
}

注意:類模板中的成員函數(shù)類外實(shí)現(xiàn)時(shí)需要加上模板的參數(shù)列表

類模板分文件編寫 1.直接包含源文件

person.h文件內(nèi)

#pragma once
#includeusing namespace std;
templateclass Person {
public:
	Person(NameType name, AgeType age);
	void showPerson();
	NameType m_Name;
	AgeType m_Age;
};

person.cpp文件內(nèi)

#include "person.h"
//構(gòu)造函數(shù)的類外實(shí)現(xiàn)
templatePerson::Person(NameType name, AgeType age) {
	this->m_Name = name;
	this->m_Age = age;
}
//成員函數(shù)的類外實(shí)現(xiàn)
templatevoid Person::showPerson() {
	cout<< "姓名:"<< this->m_Name<< "\t年齡:"<< this->m_Age<< endl;
}

執(zhí)行文件內(nèi)

//這里必須包含.cpp文件方可
#include "person.cpp"
void main() {
	Personp("lili", 18);
	p.showPerson();
}

執(zhí)行文件不可以包含.h文件必須包含.cpp問件原因:類模板中的成員函數(shù)在調(diào)用時(shí)才可以創(chuàng)建

2.將.h和.cpp文件中的內(nèi)容寫到一起,后將后綴名改為.hpp文件

person.hpp文件內(nèi)

#pragma once
#includeusing namespace std;
templateclass Person {
public:
	Person(NameType name, AgeType age);
	void showPerson();
	NameType m_Name;
	AgeType m_Age;
};

//構(gòu)造函數(shù)的類外實(shí)現(xiàn)
templatePerson::Person(NameType name, AgeType age) {
	this->m_Name = name;
	this->m_Age = age;
}
//成員函數(shù)的類外實(shí)現(xiàn)
templatevoid Person::showPerson() {
	cout<< "姓名:"<< this->m_Name<< "\t年齡:"<< this->m_Age<< endl;
}

執(zhí)行文件內(nèi)

//這里必須包含.hpp文件
#include "person.hpp"
void main() {
	Personp("lili", 18);
	p.showPerson();
}
類模板與友元

1.全局函數(shù)類內(nèi)實(shí)現(xiàn),直接在類內(nèi)聲明友元即可

templateclass Person {
	//全局函數(shù)類內(nèi)實(shí)現(xiàn)
	friend void printPerson(Personp) {
		cout<< "姓名:"<< p.m_Name<< "\t年齡:"<< p.m_Age<< endl;
	}
public:
	Person(T1 name, T2 age) {
		this->m_Name = name;
		this->m_Age = age;
	}
private:
	T1 m_Name;
	T2 m_Age;
};
void main() {
	Personp("lili", 18);
	printPerson(p);
}

2.全局函數(shù)類外實(shí)現(xiàn),需要讓編譯器知道該全局函數(shù)的存在

//編譯器需要先知道printPerson函數(shù)的存在以及Person類的存在
template< class T1, class T2 >class Person;
templatevoid printPerson(Person< T1, T2 >p) {
	cout<< "姓名:"<< p.m_Name<< "\t年齡:"<< p.m_Age<< endl;
}
templateclass Person {
	//全局函數(shù)類外實(shí)現(xiàn)
	//加空模板參數(shù)列表證明他是個(gè)模板函數(shù)
	//若全局函數(shù)是類外實(shí)現(xiàn),需要讓編譯器提前知道這個(gè)函數(shù)的存在
	friend void printPerson<>(Personp);
public:
	Person(T1 name, T2 age) {
		this->m_Name = name;
		this->m_Age = age;
	}
private:
	T1 m_Name;
	T2 m_Age;
};
void main() {
	Personp("lili", 18);
	printPerson(p);
}

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:C++之泛型編程-創(chuàng)新互聯(lián)
本文地址:http://bm7419.com/article26/gopcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、品牌網(wǎng)站制作網(wǎng)站建設(shè)、做網(wǎng)站、建站公司、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化