C++_模板初階

在面向對象中,我們可以使用重載來實現多態。

但是問題在于,重載的函數僅僅是類型不同,代碼復用率比較低,只要有新的類型出現時,就要增加對應的函數;另一方面它的代碼可維護性比較低,一個出錯可能所有的重載均出錯。

那么在C++中,我們可以使用模板來盡量避免這些問題。

一、函數模板

函數模板代表了一個函數家族,該函數模板與類型無關,在使用時被參數化,根據實參類型產生函數的特定類型版本。

函數模板格式如下:

template<typename T1, typename T2,......,typename Tn>

返回值類型 函數名(參數列表){}

其中,typename是用來定義模板參數關鍵字,也可以使用class。

要注意模板和函數之間是不需要任何符號的,并且它們可以在同一行。

下面的代碼就是使用函數模板的一個實例:

template <typename T>
void Swap(T& left,T& right)
{T temp = left;left = right;right = temp;
}

函數模板本身不是一個函數,而是“藍圖”,是編譯器用使用方式產生特定具體類型函數的模具。

模板就是將本來應該我們做的重復的事情交給了編譯器。

當使用了模板時,在編譯器編譯階段,編譯器需要根據傳入的實參類型來推演生成對應的函數,然后供調用。

假如我們用double類型使用函數模板時,編譯器通過對實參類型的推演,確定T為double,然后生成專門處理double類型參數的函數:

可以看到,類型仍然為double,變量的值也被成功交換。

實例化函數模板的方式有兩種,一種是隱式實例化,另一種是顯式實例化。

隱式實例化,即讓編譯器根據實參推演推演模板參數的實際類型,例如:

從監視1窗口可以看到,得到了正確的結果。

那么,根據剛才的Add函數模板及變量,能否這樣隱式實例化呢?

Add(num0,num2);

根據編譯器警告信息,可以明確是不可行的:

要處理這種狀況,方法有兩種,一種是用戶自己強制類型轉換:

Add((double)num0, num2);
Add(num0, (int)num2);

還有一種方法就是,顯式實例化。

只需要在函數名后的<>中指定模板參數的實際類型即可顯式實例化:

如果類型不匹配,編譯器會嘗試進行隱式類型轉換,如果無法轉換成功編譯器將會報錯。

模板參數的匹配規則如下:

1. 一個非模板函數可以和一個同名的函數模板同時存在,而且該函數模板還可以被實例化為這個非模板函數;

2. 對于非模板函數和同名函數模板,如果其他條件都相同,在調動時會優先調用非模板函數而不會從該模板產生出一個實例。如果模板可以產生一個具有更好匹配的函數, 那么將選擇模板;

3.模板函數不允許自動類型轉換,但普通函數可以進行自動類型轉換。

例如,func同時是函數,也是模板。現在在main函數中用不同的類型對其實例化,根據打印輸出結果可知,當參數為int時,調用的是函數,當參數不為int時,調用的是根據模板生成的函數:

?二、類模板

類模板是編譯器根據被實例化的類型生成具體類的模具。

在STL中,如vector,隨處可見類模板的身影:

類模板的定義格式如下:

template <class T1, class T2, ..., class Tn>
class 類模板名
{
// 類內成員定義
};

與函數模板實例化不同,類模板實例化需要在類模板名字后跟<>,然后將實例化的類型放在<>
中即可。

類模板名字不是真正的類,實例化的結果才是真正的類。

一個類模板實例化的具體例子:

??

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

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

相關文章

java實現文件的下載

系統日志的獲取不可能每次都登錄服務器&#xff0c;所以在頁面上能夠下載系統運行的日志是必須的 如何來實現日志的下載&#xff0c;這樣的一個功能 前端我們用到的是window.open(...)這樣可以發送一個get請求到后臺 后臺接收到get請求之后&#xff0c;如何實現對文件的下載 R…

ubuntu中redis+mysql安裝使用

pip -V 回車&#xff08;大寫V&#xff09;&#xff1a;python包庫安裝路徑 python -m site: python查找路徑 1、redis ubuntu安裝redis System has not been booted with systemd as init system (PID 1). Cant operate&#xff1b;該問題是systemctl start redis報錯&#…

ZLMediaKit(webrtc)在linux上(CentOS7)部署與啟動

一.ZLMediaKit(webrtc)在CentOS7部署與啟動 # 1. 卸載舊版本 yum remove git # 2. 安裝 yum 源的 Git 版本 yum install -y git # 3. 查看版本 git version # 輸出 git version 1.8.3.1配置全局環境變量 # 1. 編輯配置文件 vim /etc/profile # 2. 在 /etc/profile 文件中末尾…

用 Rufus 制作 Ubuntu 系統啟動盤時,選擇分區類型為MBR還是GPT?

當使用 Rufus 制作 Ubuntu 系統啟動盤時&#xff0c;您可以根據您的需求選擇分區類型&#xff0c;MBR&#xff08;Master Boot Record&#xff09;還是 GPT&#xff08;GUID Partition Table&#xff09;。 MBR 是傳統的分區表格式&#xff0c;適用于大多數舊版本的操作系統和舊…

2023/08/13_____JMM JAVA Memory Model JAVA內存模型

JMM JAVA Memory Model java內存模型 作用&#xff1a;緩存一致性協議&#xff0c;用于定義數據讀寫的規則&#xff08;遵守&#xff0c;找到這個規則&#xff09; JMM定義了線程2工作內存和主內存之間的抽象關系&#xff1a;線程之間的共享變量存儲在主內存&#xff08;main …

TLS協議

目錄 什么是TLS協議&#xff1f; TLS的基本流程&#xff1f; 兩種密鑰交換算法&#xff1f; 基于ECDHE密鑰交換算法的TLS握手過程&#xff1f; 基于RSA密鑰交換算法的TLS握手過程&#xff1f; 基于RSA的握手和基于ECDHE的握手有什么區別&#xff1f; 什么是前向保密&…

tp6 v3微信退款

/*** Notes:退款* param $out_trade_no 支付時候訂單號&#xff08;order表 original_bn&#xff09;兩個參數選一個這個要選對* param $out_refund_no 退款訂單號* param $total 訂單金額* param $refund 退款金額* Time: 2023-08-10*/public function refundMoney($out_trade…

oracle的異常處理

oracle提供了預定義例外、非預定義例外和自定義例外三種類型。其中&#xff1a; l預定義例外用于處理常見的oracle錯誤&#xff1b; l非預定義例外用于處理預定義所不能處理的oracle錯誤&#xff1b; l自定義例外處理與oracle錯誤無關的其他情況。 Oracle代碼編寫過程中&am…

nginx反向代理與負載均衡

負載均衡依靠反向代理實現。nginx的代理分為七層代理與四層代理&#xff1a; 七層代理&#xff1a;七層代理的就是http請求和響應。七層代理是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模塊。而且配置方法名稱&#xff1a;upstream模塊&#xff0c;不能寫…

提升效率!Go語言開發者不可錯過的必備工具集合!

&#x1f337;&#x1f341; 博主貓頭虎 帶您 Go to Golang Language.??&#x1f341; &#x1f984; 博客首頁——貓頭虎的博客&#x1f390; &#x1f433;《面試題大全專欄》 文章圖文并茂&#x1f995;生動形象&#x1f996;簡單易學&#xff01;歡迎大家來踩踩~&#x1…

UDP數據報網絡編程(實現簡單的回顯服務器,客戶端)

回顯服務器表示客戶端發的是啥&#xff0c;服務器就返回啥&#xff0c;主要是為了熟悉UDP數據報網絡編程的基本步驟 對于程序的所有分析都寫到了代碼上 UDP回顯服務器代碼 package UdpEcho;import java.io.IOException; import java.net.DatagramPacket; import java.net.Dat…

ClickHouse查看執行計劃(EXPLAIN語法)

1.EXPLAIN 語法示例 EXPLAIN [AST | SYNTAX | QUERY TREE | PLAN | PIPELINE | ESTIMATE | TABLE OVERRIDE] [setting value, ...] [ SELECT ... | tableFunction(...) [COLUMNS (...)] [ORDER BY ...] [PARTITION BY ...] [PRIMARY KEY] [SAMPLE BY ...] [T…

途樂證券-最準確的KDJ改良指標?

KDJ目標是技術剖析的一種重要目標之一&#xff0c;它是利用隨機目標&#xff08;%R&#xff09;發展而來的&#xff0c;是一種反映商場超買和超賣狀況的買賣目標。KDJ目標由快線&#xff08;K線&#xff09;、慢線&#xff08;D線&#xff09;和隨機值&#xff08;J線&#xff…

RestTemplate HTTPS請求忽略SSL證書

問題描述 使用RestTemplate發送HTTPS請求的時候&#xff0c;出現了這樣的一個問題&#xff1a; sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification …

MySQL多表查詢

1.創建student和score表 創建score表 2.為student表和score表增加記錄 向student表插入記錄的INSERT語句如下&#xff1a; 向score表插入記錄的INSERT語句如下&#xff1a; 1.查詢student表的所有記錄 2.查詢student表的第2條到4條記錄 3.從student表查詢所有學生的學號&#…

2023最新影視泛目錄系統,蘋果cms最新下載地址

影視泛目錄系統是指一種集成了電影、電視劇、綜藝節目、動漫等多種影視資源資源的系統&#xff0c;其目的是為用戶提供一個方便快捷的影視資源檢索、瀏覽、分享、評論的平臺。該系統通過對影視資源進行分類、標簽化、評分等方式&#xff0c;為用戶提供更加精準的檢索和推薦服務…

C#多線程學習 生產者和消費者

前面說過&#xff0c;每個線程都有自己的資源&#xff0c;但是代碼區是共享的&#xff0c;即每個線程都可以執行相同的函數。這可能帶來的問題就是幾個線程同時執行一個函數&#xff0c;導致數據的混亂&#xff0c;產生不可預料的結果&#xff0c;因此我們必須避免這種情況的發…

mousedown拖拽功能(vue3+ts)

因為項目有rem適配&#xff0c;使用第三方插件無法處理適配問題&#xff0c;所有只能自己寫拖拽功能了 拖拽一般都會想到按下&#xff0c;移動&#xff0c;放開&#xff0c;但是本人親測&#xff0c;就在div綁定一個按下事件就行了&#xff08;在事件里面寫另外兩個事件&#x…

爬蟲ip池越大越好嗎?

作為一名資深的程序員&#xff0c;今天我要給大家分享一些關于爬蟲ip池的知識。關于ip代理池的問題&#xff0c;答案是肯定的&#xff0c;池子越大越好。下面跟我一起來盤點一下ip池大的好處吧&#xff01; 1、提高穩定性 爬蟲ip池越大&#xff0c;意味著擁有更多可用的爬蟲ip…

「C/C++」C/C++搭建程序框架

?博客主頁何曾參靜謐的博客&#x1f4cc;文章專欄「C/C」C/C程序設計&#x1f4da;全部專欄「UG/NX」NX二次開發「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序設計「C/C」C/C程序設計「Win」Windows程序設計「DSA」數據結構與算法「File」數據文件格式 目錄 1. 分離職…