模板-C++提高編程

C++的一種編程思想稱為泛型編程,用到的技術就是模板

C++提供兩種模板:函數模板和類模板。

1.函數模板

1.函數模板作用

建立一個通用函數,其返回值類型和形參類型可以用一個虛擬的類型來代替,提高代碼復用性,將類型參數化。

2.語法

template<typename T>
//函數聲明或定義

template--聲明創建模板

typename--表明其后面的符號是一種數據類型,可以用class代替

T--通用的數據類型,名稱可以替換,通常為大寫字母

3.例子

未應用模板(代碼復雜,通用性差)

void intswap(int& a, int& b)
{int c;c = a;a = b;b = c;
}
void doubleswap(double& a, double& b)
{double c;c = a;a = b;b = c;
}

應用模板(代碼簡潔,通用性強)

注意:函數模板一次只能對應一個函數,也就是說T不能多次重復使用

template<typename T>
void swap(T& a, T& b)
{T c;c = a;a = b;b = c;
}

4.模板使用方式

1.自動類型推導

swap(a,b);

2.顯示指定類型

swap<int>(a,b);

5.注意事項

1.自動類型推導

必須推導出一只的數據類型T才可以使用

反例:

#include<iostream>
using namespace std;
#include<string>
template<typename T>
void swap(T& a, T& b)
{T c;c = a;a = b;b = c;
}
int main()
{int a=0;char b = '12';swap(a, b);return 0;
}

2.T的類型必須確定

模板必須要確定T的類型,才可以使用

反例:

#include<iostream>
using namespace std;
#include<string>
template<typename T>
void swap()
{cout << "swap" << endl;
}
int main()
{swap();return 0;
}

6.案例

1.題目

對數組進行降序排序

2.代碼
#include<iostream>
using namespace std;
#include<string>
template<typename T>
void sort(T a[],int len)
{T temp;int max ;for (int i = 0; i < len; i++){max = i;for (int j = i; j < len; j++){if (a[j] > a[max]){temp = a[j];a[j] = a[max];a[max] = temp;}}}
}
int main()
{char c[6] = "badce";sort(c,5);cout << c << endl;int a[6] = {4,5,2,3,1};sort(a, 5);for(int i=0;i<5;i++)cout << a[i] << endl;return 0;
}
3.結果

7.普通模板與函數模板區別

·普通函數可以發生自動類型轉換(隱式類型轉換)

·函數模板調用時,如果利用自動類型推導,則不會發生隱式類型轉換

·如果利用顯示指定類型的方式,可以發生隱式類型轉換

1.普通函數隱式類型轉換
#include<iostream>
using namespace std;
#include<string>
int fun(int a, int b)
{return a + b;
}
int main()
{int a = 10;char c = 'c';//a=97,c=99cout << fun(a, c) << endl;return 0;
}

2.自動類型推導不可以使用
#include<iostream>
using namespace std;
#include<string>
template<typename T>
int fun(T a, T b)
{return a + b;
}
int main()
{int a = 10;char c = 'c';cout << fun(a, c) << endl;return 0;
}

3.顯式指定類型可以使用
#include<iostream>
using namespace std;
#include<string>
template<typename T>
int fun(T a, T b)
{return a + b;
}
int main()
{int a = 10;char c = 'c';cout << fun<int>(a, c) << endl;return 0;
}

4.建議

建議使用顯式指定類型的方式調用,這種更加明確。

8.普通函數與函數模板調用規則

1.函數模板可以發生重載
1.普通函數與函數模板重載
#include<iostream>
using namespace std;
#include<string>
template<typename T>
void fun(T a)
{cout << "函數模板" << endl;
}
void  fun()
{cout << "普通函數" << endl;
}
int main()
{fun(1);fun();return 0;
}

2.函數模板之間的重載
#include<iostream>
using namespace std;
#include<string>
template<typename T>
void fun(T a)
{cout << "函數模板" << endl;
}
template<typename T>
void fun(T a,T b)
{cout << "重載函數模板" << endl;
}
int main()
{fun(1);fun(1, 1);return 0;
}
2.調用優先級

如果普通函數和函數模板都可以調用,優先調用函數模板

#include<iostream>
using namespace std;
#include<string>
template<typename T>
void fun(T a)
{cout << "函數模板" << endl;
}
void  fun( int a)
{cout << "普通函數" << endl;
}
int main()
{fun(1);return 0;
}

注意:就算普通函數只有一個聲明也不會調用函數模板(會報錯)。

#include<iostream>
using namespace std;
#include<string>
template<typename T>
void fun(T a)
{cout << "函數模板" << endl;
}
void  fun(int a);
int main()
{fun(1);return 0;
}

3.強制調用模板函數

通過空模板參數列表,強制調用函數模板

fun<>(1);
4.發生隱式類型轉換時的優先級

當普通函數發生隱式類型轉換時,會優先調用函數模板(程序會使用最優選擇)

#include<iostream>
using namespace std;
#include<string>
template<typename T>
void fun(T a)
{cout << "函數模板" << endl;
}
void fun(char a)
{cout << "普通函數調用" << endl;
}
int main()
{fun(1);return 0;
}

2.類模板

1.定義

建立一個通用類,類中的成員數據類型可以不具體指定,用一個虛擬的類型來代替。

2.語法

template<typename T>
//類

template--聲明創建模板

typename--表明其后面的符號是一種數據類型,可以用class代替

T--通用的數據類型,名稱可以替換,通常為大寫字母

3.例子

#include<iostream>
using namespace std;
#include<string>
template<class A,class B>
class person
{
public:person(A name, B age){this->name = name;this->age = age;}void show(){cout << this->name << this->age << endl;}A name;B age;
};
int main()
{person<string, int>p1("孫悟空", 999);p1.show();return 0;
}

4.類模板與函數模板區別

1.類模板不可以使用自動類型推導,只能自己設置類型。

2.類模板的模板參數列表中可以默認參數

模板參數表:即為尖括號里面的

template<class A,class B>

默認參數

template<class A,class B=int>

5.類模板中的成員函數創建時機

只要不去調用,就不會創建,所以a.fun()不會報錯

#include<iostream>
using namespace std;
#include<string>
template<class A>
class person
{
public:A a;void fun(){a.fun1();}
};
int main()
{return 0;
}

6.類模板對象做函數參數

#include<iostream>
using namespace std;
#include<string>
template<class A,class B>
class person
{
public:A name;B age;person(A name, B age){this->name = name;this->age=age;}void show(){cout << this->name << endl;cout << this->age << endl;}
};
void fun(person<string, int>&p1)
{p1.show();
}
int main()
{person<string, int>p1("孫悟空", 100);fun(p1);return 0;
}

此時的函數參數應該是“person<string, int>&p1”

7.函數模板參數模板化

使用函數模板來提高復用性

#include<iostream>
using namespace std;
#include<string>
template<class A,class B>
class person
{
public:A name;B age;person(A name, B age){this->name = name;this->age=age;}void show(){cout << this->name << endl;cout << this->age << endl;}
};
template<class T1,class T2>
void fun(person<T1, T2>&p1)
{p1.show();
}
int main()
{person<string, int>p1("孫悟空", 100);fun(p1);return 0;
}

1.類型顯示方法

如果想顯示出自動類型轉換的類型是什么,可以用這個方法

#include<iostream>
using namespace std;
#include<string>
template<class A,class B>
class person
{
public:A name;B age;person(A name, B age){this->name = name;this->age=age;}void show(){cout <<"姓名:" << this->name << endl;cout << "年齡:" << this->age << endl;}
};
template<class T1,class T2>
void fun(person<T1, T2>&p1)
{p1.show();cout <<"T1的類型:" << typeid(T1).name() << endl;cout <<"T2的類型:" << typeid(T2).name() << endl;
}
int main()
{person<string, int>p1("孫悟空", 100);fun(p1);return 0;
}

8.將做參數的整個類都模板化

#include<iostream>
using namespace std;
#include<string>
template<class A,class B>
class person
{
public:A name;B age;person(A name, B age){this->name = name;this->age=age;}void show(){cout <<"姓名:" << this->name << endl;cout << "年齡:" << this->age << endl;}
};
template<class T>
void fun(T &p1)
{p1.show();cout << "T的數據類型:" << typeid(T).name() << endl;
}
int main()
{person<string, int>p1("孫悟空", 100);fun(p1);return 0;
}

9.類模板與繼承

父類如果是一個模板,子類在繼承時需要指出他的數據類型

1.手動指定數據類型
#include<iostream>
using namespace std;
#include<string>
template<class T>
class base
{
public:T a;
};
class son :public base<int>
{};
int main()
{return 0;
}
2.將子類也變為模板
#include<iostream>
using namespace std;
#include<string>
template<class T>
class base
{
public:T a;
};
template<class T1,class T2>
class son :public base<T2>
{
public:T1 a;
};
int main()
{son<string, int>p1;return 0;
}

10.類模板的函數類外實現

1.構造函數的類外實現
#include<iostream>
using namespace std;
#include<string>
template<class T1,class T2>
class person
{
public:T1 name;T2 age;person(T1 name, T2 age);
};
template<class T1,class T2>
person<T1,T2>::person(T1 name,T2 age)
{this->name = name;this->age = age;
}
int main()
{return 0;
}
2.成員函數的類外實現
#include<iostream>
using namespace std;
#include<string>
template<class T1,class T2>
class person
{
public:T1 name;T2 age;person(T1 name,T2 age);void fun();
};
template<class T1, class T2>
person<T1, T2>::person(T1 name, T2 age)
{this->name = name;this->age = age;
}
template<class T1,class T2>
void person<T1, T2>::fun()
{cout << name << endl;cout << age << endl;
}
int main()
{person<string, int>p("埃里給", 18);p.fun();return 0;
}

11.類模板分文件編寫

該程序包含一個頭文件和一個源文件,頭文件負責函數實現,源文件負責函數調用

.hpp后綴名:約定俗成的包含類模板的聲明與實現。

1.頭文件(person.hpp)
#pragma once
#include<iostream>
using namespace std;
#include<string>
template<class T1, class T2>
class person
{
public:person(T1 name, T2 age);void show();T1 name;T2 age;
};
template<class T1, class T2>
person<T1, T2>::person(T1 name, T2 age)
{this->name = name;this->age = age;
}
template<class T1, class T2>
void person<T1, T2>::show()
{cout << name << endl;cout << age << endl;
}
2.源文件
#include"person.hpp"
int main()
{person<string,int>p("埃里給", 18);p.show();return 0;
}
3.輸出結果

12.類模板與友元

不想寫了,想寫的時候補上

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73447.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73447.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73447.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Asp.net的物流配送管理系統

作者&#xff1a;計算機學姐 開發技術&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源碼”。 專欄推薦&#xff1a;前后端分離項目源碼、SpringBoot項目源碼、Vue項目源碼、SSM項目源碼、微信小程序源碼 精品專欄&#xff1a;…

順序表和鏈表的對比(一)

前言 今天給小伙伴們分享的是在數據結構中順序表和鏈表的對比。它們在計算機科學和軟件開發中具有廣泛的應用&#xff0c;是理解更復雜數據結構&#xff08;如棧、隊列、樹、圖等&#xff09;的基礎。這次將會給大家從定義初始化&#xff0c;以及功能增刪查改上進行詳細對比&a…

星越L_外后視鏡使用講解

目錄 1.外后視鏡調節 2后視鏡折疊 3.后視鏡加熱 1.外后視鏡調節 L控制左邊后視鏡調節,上下撥動調整視野,一般此鏡左右21分,上下55開。 R控制左邊后視鏡調節,上下撥動調整視野,一般此鏡左右13分,上下55開。 2后視鏡折疊 車輛解鎖自動展開 車輛關閉自動折疊 嚴寒天氣…

DevOps實踐:持續集成與持續部署完全指南

文章目錄 引言&#xff1a;從人工到自動化的進化革命一、CI/CD核心認知升級1.1 持續集成 vs 持續部署 vs 持續交付1.2 中小團隊為什么要實施CI/CD&#xff1f; 二、CI/CD工具鏈選型指南2.1 中小團隊推薦技術棧2.2 工具對比決策矩陣 三、實戰五步構建企業級流水線3.1 基礎環境搭…

【數據結構】數據結構,算法 概念

0.本篇問題&#xff1a; 數據、數據元素、數據對象、數據項之間的基本關系&#xff1f;ADT是什么&#xff1f;數據結構的三要素&#xff1f;數據的邏輯結構有哪些&#xff1f;數據的存儲結構有哪些&#xff1f;算法的五個特征&#xff1f;O(1) O(logn) O(n^n) O(n) O(n^2…

同步Oracle及mysql至KADB的KFS配置文件參考

Oracle源端flysync.ini文件 注意&#xff1a;oracle用戶名大寫 mysql源端flysync.ini文件 附&#xff1a;目標端KADB的flysync.ini文件 [m_kes_3113] 源端為KES kufl-port3113 datasource-typekingbase rolemaster replication-host10.4.43.53 replication-port54321 …

PECL(Positive Emitter-Coupled Logic)電平詳解

一、PECL電平的定義與核心特性 PECL&#xff08;正射極耦合邏輯&#xff09;是一種基于 射極耦合邏輯&#xff08;ECL&#xff09;技術 的高速差分信號標準&#xff0c;采用 正電源供電&#xff08;如5V或3.3V&#xff09;。其核心特性包括 高速傳輸、低噪聲、強抗干擾能力&am…

以 ArcGIS Pro 為筆,繪就水墨地圖畫卷

一、引言 水墨畫&#xff0c;作為中國傳統繪畫藝術的瑰寶&#xff0c;以其獨特的韻味和表現力&#xff0c;在藝術領域占據著重要地位。它通過水與墨的交融&#xff0c;展現出山水之間的靈動與韻味。 而將這種藝術形式與現代地理信息系統&#xff08;GIS&#xff09;技術相結合…

軟考網絡安全專業

隨著信息技術的迅猛發展&#xff0c;網絡安全問題日益凸顯&#xff0c;成為社會各界普遍關注的焦點。在這樣的背景下&#xff0c;軟考網絡安全專業應運而生&#xff0c;為培養高素質的網絡安全人才提供了有力支撐。本文將對軟考網絡安全專業進行深入剖析&#xff0c;探討其在信…

在線 SQL 轉 SQLAlchemy:一鍵生成 Python 數據模型

一款高效的在線 SQL 轉 SQLAlchemy 工具&#xff0c;支持自動解析 SQL 語句并生成 Python SQLAlchemy 模型代碼&#xff0c;適用于數據庫管理、后端開發和 ORM 結構映射。無需手寫 SQLAlchemy 模型&#xff0c;一鍵轉換 SQL 結構&#xff0c;提升開發效率&#xff0c;簡化數據庫…

自定義tiptap插件

本文為開發開源項目的真實開發經歷&#xff0c;感興趣的可以來給我的項目點個star&#xff0c;謝謝啦~ 具體博文介紹&#xff1a; 開源&#xff5c;Documind協同文檔&#xff08;接入deepseek-r1、支持實時聊天&#xff09;Documind &#x1f680; 一個支持實時聊天和接入 - 掘…

網絡安全需要學多久才能入門?

網絡安全是一個復雜且不斷發展的領域&#xff0c;想要入行該領域&#xff0c;我們需要付出足夠多的時間和精力好好學習相關知識&#xff0c;才可以獲得一份不錯的工作&#xff0c;那么網絡安全需要學多久才能入門?我們通過這篇文章來了解一下。 學習網絡安全的入門時間因個人的…

EG82088串口邊緣計算網關

EG82088串口邊緣計算網關 EG8208是一款專業級8路獨立隔離型RS485通訊控制器,通過Modbus及JSON支持、靈活的TCP/IP和UDP切換、內置監控自診斷等特性,廣泛應用于工業自動化、樓宇管理等領域,為用戶提供卓越的數據采集和設備管理解決方案。 接口類型&#xff1a;8RS485/8DO/1LAN協…

Linux下GCC和C++實現帶多組標簽的Snowflake SQL查詢批量數據導出程序

設計一個基于多個帶標簽Snowflake SQL語句作為json配置文件的Linux下GCC的C代碼程序&#xff0c;實現根據不同的輸入參數自動批量地將Snowflake數據庫的數據導出為CSV文件到本地目錄上&#xff0c;標簽加擴展名.csv為導出數據文件名&#xff0c;文件已經存在則覆蓋原始文件。需…

Trae AI 輔助修復uniapp 微信小程序的Bug

一、transparent的兼容問題 設計稿&#xff1a; 實際在iphone 6 plu上&#xff1a; 直接讓Trae AI修復&#xff1a; 修改后驗證通過。 二、v-if分支中子元素根據輸入框中內容長度動態添加class樣式失效 遇到了個“怪問題”&#xff0c;在其他手機或者開發者工具都正常。也…

conda install 和 pip install 的區別

conda install 和 pip install 是兩個常用的包安裝命令&#xff0c;但它們在很多方面存在差異。 1. 所屬管理系統不同 1.1 conda install conda install 是Anaconda和Miniconda發行版自帶的包管理工具 conda 的安裝命令。conda 是一個跨平臺的開源包管理系統和環境管理系統&…

uni-app App 端分段導出 JSON 數據為文件

在開發過程中&#xff0c;我們經常需要將大量數據導出為 JSON 文件&#xff0c;尤其是在處理長列表或大數據集時。然而&#xff0c;直接將所有數據寫入一個文件可能會導致性能問題&#xff0c;尤其是在移動設備上。為了優化性能并提高用戶體驗&#xff0c;我們可以將數據分段導…

視頻推拉流EasyDSS案例分析:互聯網直播/點播技術與平臺創新應用

隨著互聯網技術的快速發展&#xff0c;直播/點播平臺已成為信息傳播和娛樂的重要載體。特別是在電視購物領域&#xff0c;互聯網直播/點播平臺與技術的應用&#xff0c;不僅為用戶帶來了全新的購物體驗&#xff0c;也為商家提供了更廣闊的營銷渠道。傳統媒體再一次切實感受到了…

MySQL再次基礎 向初級工程師邁進

作者&#xff1a;在計算機行業找不到工作的大四失業者 Run run run ! ! ! 1、MySQL概述 1.1數據庫相關概念 1.2MySQL數據庫 2、SQL 2.1SQL通用語法 SQL語句可以單行或多行書寫&#xff0c;以分號結尾。SQL語句可以使用空格/縮進來增強語句的可讀性。MySQL數據庫的SQL語句不區…

手寫一個簡易版的tomcat

Tomcat 是一個廣泛使用的開源 Servlet 容器&#xff0c;用于運行 Java Web 應用程序。深入理解 Tomcat 的工作原理對于 Java 開發者來說是非常有價值的。本文將帶領大家手動實現一個簡易版的 Tomcat&#xff0c;通過這個過程&#xff0c;我們可以更清晰地了解 Tomcat 是如何處理…