c++模板與泛型編程

模板的作用:通過使用模板降低重復代碼的編寫,把已經寫好的代碼作用最大化;

模板的概念

1.模板與泛型編程(目的時只進行邏輯操作,不需要考慮數據類型,將類型作為參數傳遞)

模板是實現代碼重用的一種工具或方法,用于完成某種功能或解決某種問題,模板的作用就是實現類型參數化。

模板就是泛型編程的前置條件,屬于充分但不必要條件;

總而言之:泛型編程就是為了編寫和數據類型沒有關系的邏輯代碼,而模板就是為了實現代碼邏輯和數據類型沒有關系抽象的數據類,是泛型編程的先決條件;

2.模板分類

函數模板:

函數模板用于定義模板函數,模板函數就是用模板生成的函數;

類模板

類模板用于定義模板類,模板類就是用類模板定義出來的類;

總而言之:模板作用于函數就是函數模板,模板作用于類就是類模板;

函數模板和普通函數對比:

1.只要滿足重載條件都可以構成重載,模板函數和普通函數之間只要滿足重載條件都可以構成重載;

2.同時出現模板函數和普通函數重載,相同情況下編譯器默認優先調用普通函數;

3.如果需要強制調用模板函數,可以使用顯式調用的方式去調用指定的模板函數;

4.模板的局限性

// 通過函數模板定義模板函數
// 語法:
// 定義:
// template用于定義模板的關鍵字,typename(class)用于定義類型的關鍵字,Type_n為自定義的類型名稱
// template <typename Tpe_1, ... , typename Type_n>
// 返回值類型 函數名(形參列表)
// {
//      函數體;
// }
// 調用:
// 函數名<指定類型>(參數列表)#include <iostream>
#include <string>using namespace std;template <typename T1, typename T2>
T1 add(T1 a, T2 b)
{return a + b;
}// class也可以用于定義類型,但是一般都用typename代替class就行
template <class TT1, class TT2>
void test1(TT1 tt1, TT2 tt2)
{cout << "tt1 = " << tt1 << ", tt2 = " << tt2 << endl;
}// class也可以用于定義類型,但是一般都用typename代替class就行
template <typename TY1, typename TY2>
void test2(TY1 tt1, TY2 tt2)
{cout << "tt1 = " << tt1 << ", tt2 = " << tt2 << endl;
}int main()
{// test1// 隱式推導類型,由編譯器指定cout << "test1 : " << endl;test1(1, 2);test1(1.123, 2.123);test1("name", 'A');// test2cout << "test2 : " << endl;test2(1, 2);test2(1.123, 2.123);test2("name", 'A');// add測試cout << "add(3, 4) = " << add(3, 4) << endl;cout << "add(1.23, 1.24) = " << add(1.23, 1.24) << endl;// add(6, 2.46) = 8 輸出的數據類型由編譯器決定,這里返回值設置為int類型cout << "add(6, 2.46) = " << add(6, 2.46) << endl;cout << "add<int>(6, 2.46) = " << add<int>(6, 2.46) << endl;cout << "add<double>(6, 2.46) = " << add<double>(6, 2.46) << endl;// 模板函數調用,顯式指定類型,告訴編譯器按照指定類型操作// const char *就是string類型test1<const char *, char>("name", 'A');return 0;
}
// 模板的局限性
#include <iostream>
#include <string>using namespace std;template <typename T>
bool IsDataEqual(T a, T b)
{if (a == b) {return true;}return false;
}class MyData
{
public:int m_num;int m_val;// 添加默認構造函數,如果有自定義構造函數后系統將不會再分配默認的構造函數// 如果沒有沒有這個無參構造函數,那么通過MyData obj1, obj2;方式定義對象時會報錯如下:// error: no matching function for call to ‘MyData::MyData()’MyData obj1, obj2;MyData() : m_num(0) {}// 自定義帶參構造函數MyData(int n) : m_num(n) {}
};class MyClass
{
public:int m_num;int m_val;// 如果加上設置默認缺省參數值,可以使用MyClass obj創建對象,此時這個對象擁有設置的默認缺省參數值MyClass(double n = 5.0, double val = 6.0) : m_num(n), m_val(val) {}
};// 對自定義數據類型的對象需要自定義規則進行比較
template<typename TT> bool MyCompare(const TT &a, const TT &b)
{if (a.m_num == b.m_num) {return true;}return false;
} int main()
{int num = 5, val = 5;cout << boolalpha << IsDataEqual(num, val) << endl;val = 6;cout << (IsDataEqual(num, val) ? "true" : "false") << endl;cout << (IsDataEqual<int>(num, val) ? "true" : "false") << endl;// 自定義數據類型比較MyData obj1(5), obj2(5);// 如果沒有重載==運算符,不同對象之間不可以使用模板函數進行比較cout << (MyCompare(obj1, obj2) ? "true" : "false") << endl;cout << (MyCompare<MyData>(obj1, obj2) ? "true" : "false") << endl;MyClass obj;cout << "obj.m_num = " << obj.m_num << ", obj.m_val = " << obj.m_val << endl;return 0;
}
// 模板類
// 語法:
// template<類型參數列表>
// class 模板類類名
// {
//     成員;
// }; // 定義域需要加";"// 類型參數列表:<class T1, ..., class Tn>
// 成員:T1 name; ... Tn#include <iostream>
#include <string>using namespace std;// 數據參數可用默認值,數據類型也可以使用默認值
// 默認類型可以有,也可以不寫
// template <class Type1 = int, class Type2 = double>
template <class Type1, class Type2>
class MyData
{
private:Type1 m_num;Type2 m_val;
public:MyData(Type1 n = 0, Type2 v = 0.0) : m_num(n), m_val(v) {}// get/set 內聯Type1 GetNum() {return m_num;}Type2 GetVal() {return m_val;}void SetNum(Type1 n) {m_num = n;}void SetVal(Type2 v) {m_val = v;}void showData();
};// 模板類需要給定類型才能完整,沒給類型就不是完整類
template <typename T1, typename T2>
void MyData<T1, T2>::showData()
{cout << "num = " << m_num << ", val = " << m_val << endl;
}// 1.普通全局函數
// 普通全局函數,指定MyData類型的對象并指定模板類對象的參數
// 這種寫法只能接收類型匹配的參數對象
void testFunc_1(MyData<int, double> &obj)
{cout << "testFunc_1(MyData<int, double> &obj) : " ;obj.showData();
}// 2.函數參數模板化
template <typename TT1, typename TT2>
void testFunc_2(MyData<TT1, TT2> & obj)
{cout << "testFunc_2(MyData<TT1, TT2> & obj)  : " ;obj.showData();
}// 3.整個類作為一個類型,整體參數作為一個模板傳輸
template <class T>
void testFunc_3(T & obj)
{cout << "testFunc_3(T & obj)  : " ;obj.showData();
}int main()
{// 如果沒有設置默認參數類型則需要指定參數類型// template <class Type1, class Type2> // 未指定默認參數類型MyData<int, double> data_1(3, 3.14);testFunc_1(data_1);// 如果有設置默認參數類型,<>中可以不指定數據類型// template <class Type1 = int, class Type2 = double> // 指定默認參數類型// MyData<> data_1(3, 3.14);data_1.showData();// 模板類可以在創建對象的時候指定對象中的類型MyData<char, double> data_2(67, 3.14);data_2.showData();// 隱式調用,不指定參數類型testFunc_2(data_2);// 顯示調用,指定參數類型testFunc_2<int, double>(data_1);MyData<char, float> data_3(68, 3.14);data_3.showData();// 通過以上測試可以看出同一種類型的對象數據類型不一樣,這就是模板類的功能testFunc_3(data_1);testFunc_3<MyData<int, double>>(data_1);testFunc_3(data_2);testFunc_3<MyData<char, double>>(data_2);testFunc_3(data_3);testFunc_3<MyData<char, float>>(data_3);return 0;
}

// 類模板的繼承
// 注意事項:
// 寫模板時需要將類的聲明和實現都寫在同一個文件中
#include <iostream>
#include <string>using namespace std;template <class FType>
class Father
{
public:FType m_f_val;
};// 子類繼承父類時需要指定參數類型
class Son : public Father<int>
{
public:int m_s_val;
};// 子類本省也可以是一個模板
template <class SType1, class SType2>
class Son1 : public Father<SType1>
{
public:int m_s_val;
};int main()
{Son1<int, double> obj_son;obj_son.m_f_val;obj_son.m_s_val;return 0;
}
// 模板與友元之間的關系
// 相當于就是在類模板中使用友元函數
#include <iostream>
#include <string>using namespace std;// 模板類友元函數能不用就不用,
// 如果非得要用,在類中聲明時需要在函數名后邊加上一個<>,實現函數體定義的時候不能在函數名后邊加<>
// 需要在模板類友元函數前面先聲明類
// 還需要在模板類友元函數前面聲明函數
// 以下4行聲明代碼其實只需要先聲明void show_2(A<T> & obj);函數即可
// 但是void show_2(A<T> & obj);函數聲明的時候需要聲明類型T,即template <typename T>
// template <typename T>聲明類型T的時候發現類A也需要提前聲明
// class A;聲明類A的時候也得提前聲明模板類型,即template <class T>
// 所以就有了以下4行聲明
template <class T>
class A;
template <typename T>
void show_2(A<T> & obj);// 只設置一個類型,并設置默認參數類型為int,當然也可以不設置默認類型
template <class T = int>
class A
{
public:A(T t = 0) : m_a(t) {}private:T m_a;// C++ 中友元函數 `friend` 的權限與其在類中聲明的訪問權限是無關的,// 即無論它是在 `public`、`protected` 或 `private` 聲明的,它的訪問權限都是類外的,可以訪問類的私有成員。// 當在類中聲明一個函數為 `friend`,其實質上是將這個函數的訪問權限放寬到了類的外部,使它可以訪問類的私有成員。// 因此,友元函數的訪問權限不受類的訪問控制修飾符所限制。// 需要注意的是,友元關系是單向的,即如果類 A 作為類 B 的友元,不一定意味著類 B 作為類 A 的友元。// 另外,友元關系是不能被繼承的,即派生類無法訪問基類中的友元函數。friend void show_1(A<T> & obj) {cout << "show_1() : " << obj.m_a << endl;}// 其實友元函數一般只在類中聲明,類外定義// show_2中的T與上文中的T沒有任何聯系,巧合,都稱之為T// 只有在聲明的時候需要在函數名后邊寫<>,在實現定義的時候不需要加<>friend void show_2<>(A<T>& obj);};template <typename T>
// 只有在聲明的時候需要在函數名后邊寫<>,在實現定義的時候不需要加<>
void show_2(A<T> & obj)
{cout << "show_2() : " << obj.m_a << endl;
}int main()
{A<int> obj_a(666);show_1(obj_a);show_2(obj_a);return 0;
}

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

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

相關文章

【軟件設計師】程序語言

1.程序設計語言基本概念 1.1 低級語言與高級語言 低級語言&#xff1a;機器語言和匯編語言稱為低級語言 機器語言指0.&#xff0c;1組成的機器指令序列 匯編語言指用符號表示指令的語言&#xff0c;如MOV AX&#xff0c;2 高級語言&#xff1a;從人類的邏輯角度出發&#xff0…

numpy-mkl的下載地址

不要使用pip3直接在終端安裝&#xff0c;因為pip3默安裝的是numpy&#xff0c;而不是numpymkl。 采用在第三方庫中手動下載后&#xff0c;再安裝的方式。 第三方庫網址&#xff1a;https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy 如果不能進入就可以選擇去git里面&#x…

(三)MobaXterm、VSCode、Pycharm ssh連接服務器并使用

背景&#xff1a;根據前兩篇文章操作完成后&#xff0c; 手把手教學&#xff0c;一站式安裝ubuntu及配置服務器-CSDN博客 手把手教學&#xff0c;一站式教你實現服務器&#xff08;Ubuntu&#xff09;Anaconda多用戶共享-CSDN博客 課題組成員每人都有自己的帳號了&#xff0…

嵌入式0基礎開始學習 Ⅲ Linux基礎(3)正則表達式

0.問題引入 字符串是計算機應用中最為廣泛的處理對象之一(瀏覽器&#xff0c;xml文件&#xff0c;代碼) 并且字符串的組合規則形式各種各樣&#xff0c;如&#xff1a; 數字字符串 email字符串 IP地址字符串 網址 …

互聯網政務應用安全管理規定:使用安全連接方式訪問

前幾日&#xff0c;由中央網絡安全和信息化委員會辦公室、中央機構編制委員會辦公室、工業和信息化部、公安部等4部門聯合制定的《互聯網政務應用安全管理規定》&#xff08;以下簡稱規定&#xff09;發布了&#xff0c;規定定義了互聯網政務應用&#xff0c;也對互聯網政務應用…

Android數據緩存框架 - 內存數據載體從LiveData到StateFlow

引言&#xff1a;所有成功者的背后&#xff0c;都有一份艱苦的歷程&#xff0c;不要只看到了人前的風光&#xff0c;而低估了他們背后所付出的努力。 隨著flow到流行度越來越高&#xff0c;有開發者呼吁我使用flow&#xff0c;于是我就如你們所愿&#xff0c;新增了StateFlow作…

智能時代下,人機交互和虛擬現實的機遇和挑戰

智能時代下,人機交互和虛擬現實的機遇和挑戰

多態(C++)

多態(C) 本文如果有錯誤或者不足的地方&#xff0c;希望各位大佬多多指點。 【本文目錄】 1.多態的概念2.多態的定義及實現3.抽象類4.多態的原理5.單繼承和多繼承的虛函數表 1.多態的概念 多態的概念就是&#xff1a;多種形態 多態就是可以有多種的形態。不同的身份去實現同一…

【Leetcode 160】環形鏈表——雙指針,細節講解

題目 給你一個鏈表的頭節點 head &#xff0c;判斷鏈表中是否有環。 如果鏈表中有某個節點&#xff0c;可以通過連續跟蹤 next 指針再次到達&#xff0c;則鏈表中存在環。 為了表示給定鏈表中的環&#xff0c;評測系統內部使用整數 pos 來表示鏈表尾連接到鏈表中的位置&#…

RTSP/Onvif安防視頻監控云平臺EasyNVR重啟后通道在線視頻無法播放,接口報錯502是什么原因?

EasyNVR安防視頻云平臺是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif協議接入的安防監控流媒體視頻云平臺。平臺具備視頻實時監控直播、云端錄像、云存儲、錄像檢索與回看、告警等視頻能力&#xff0c;能對接入的視頻流進行處理與多端分發&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

hypack如何采集多波束數據?(下)

多波束測量模塊 1&#xff09;記錄多波束和輔助傳感器的數據&#xff1b; 2&#xff09;顯示實時改正后的數據和數據質量信息。 ?編輯? 測量準備 1&#xff09;設置大地測量參數和硬件設置&#xff1b; 2&#xff09;計劃測線 計劃測線是一定間距的平行線&#xff0c;…

微軟聯手清華,AI注釋讓文本到圖像生成更符合人類偏好

獲取本文論文原文PDF&#xff0c;請在公眾號【AI論文解讀】留言&#xff1a;論文解讀 摘要 本研究展示了利用人類偏好數據集來精細調整文本到圖像生成模型的潛力&#xff0c;增強了生成圖像與文本提示之間的一致性。盡管取得了進展&#xff0c;現有的人類偏好數據集要么構建成…

掌控安全CTF-2024年5月擂臺賽-WP(部分)

MISC ez_Misc 題目給了一個加密的壓縮包和一個文本文檔&#xff0c;首先我們先來看文本的內容&#xff0c;如下&#xff1a; 很容易看出&#xff0c;0寬隱寫&#xff0c;用PuzzleSolver梭哈一下&#xff0c;發現了&#xff1a;Thi3 is n0t 2 hint 又在文本中發現一個特征&…

【2024】高校網絡安全管理運維賽

比賽時間&#xff1a;2024-05-06 Re-easyre 基本的base64換表&#xff0c;用CyberChef解密 Re-babyre 進入主函數&#xff0c;發現輸入四次 看一下就知道是大數求解 (當初寫的時候差不多 不知道為什么第四個總是算錯…) from z3 import *s Solver() # 設置一個解方程的類…

中心滲透Ⅱ

cs與msf權限傳遞以及mimikatz抓取win2012明文密碼 使用Cobalt Strike抓取win2012明文密碼&#xff0c;將會話傳遞到Metasploit Framework上 1.cs生成木馬并使目標服務器中馬 建立監聽生成木馬 2.抓取目標主機的明文密碼 通過修改注冊表來讓Wdigest Auth保存明文口令 shell …

技術就緒度

技術就緒度&#xff08;Technology Readiness Level&#xff0c;簡稱TRL&#xff09;這個術語中的每個字符可以這樣理解&#xff1a; 技術&#xff08;Technology&#xff09;&#xff1a;指的是正在研發或評估的具體的技術、工具、材料或方法。這可以是一套軟件程序、一個物理…

一分鐘揭秘面試官真實意圖,穩拿offer的面試秘訣!

想要在面試中脫穎而出&#xff0c;順利獲得心儀的offer嗎&#xff1f;那么&#xff0c;你需要了解面試官背后的潛臺詞。通過解析這些潛臺詞&#xff0c;你將能更準確地把握面試官的期望&#xff0c;并給出他們最喜歡的回答。下面&#xff0c;就讓我們一起揭開這層神秘的面紗&am…

深入pandas:數據分析

目錄 前言 第一點&#xff1a;導入模塊 第二點&#xff1a;準備數據 第三點&#xff1a;簡單的分析數據 第四點&#xff1a;【重點】數據透支 總結 前言 在數據分析與挖掘的領域&#xff0c;了解如何使用工具和方法來探索數據是至關重要的。本文將探討如何利用Python中的…

C語言常用字符串處理函數

C語言中包含了很多對字符串處理的函數,要使用這些函數&#xff0c; 首先需要導入頭文件#include <string.h> 1. strlen() -- 計算字符串長度 原型: size_t strlen(char const *string); 例: char *str "abcde"; size_t len strlen(str); // 結果為…

【DevOps】Elasticsearch在Ubuntu 20.04上的安裝與配置:詳細指南

目錄 一、ES 簡介 1、核心概念 2、工作原理 3、 優勢 二、ES 在 Ubuntu 20.04 上的安裝 1、安裝 Java 2、下載 ES 安裝包 3、創建 ES 用戶 4 、解壓安裝包 5、 配置 ES 6、 啟動 ES 7、驗證安裝 三、ES 常用命令 1、創建索引 2、 插入文檔 3、查詢文檔 四、ES…