最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++模板Template詳解及其作用介紹

 更新時間:2022年06月14日 09:05:05   作者:原來45  
這篇文章主要介紹了C++中模板(Template)的詳解及其作用介紹,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1. 模板

首先模板分為函數模板和類模板

想到模板,就會聯想到泛型編程

泛型編程:編寫與類型無關的通用代碼,是代碼復用的一種手段。模板是泛型編程的基礎。

網圖:

在之前,我們已經知道了函數重載

還是那一個例子 Swap函數交換 int double char

哪怕是函數重載,我們也要寫三個,但是如果有了模板,我們只需要:

告訴編譯器一個模板,讓編譯器根據不同的類型利用該模板來生成代碼

2. 函數模板

2.1 函數模板概念

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

2.2 函數模板格式

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

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

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

注意: typename 是 用來定義模板參數 關鍵字 , 也可以使用 class( 切記:不能使用 struct 代替 class)

2.3 函數模板原理

函數模板是一個藍圖,它本身并不是函數,是編譯器用使用方式產生特定具體類型函數的模具。 所以其實模板就是將本來應該我們做的重復的事情交給了編譯器。 簡單說就是本來我們應該多去寫的Swap的重復工作去給編譯器做了 網圖:

在編譯器編譯階段 ,對于模板函數的使用, 編譯器需要根據傳入的實參類型來推演生成對應類型 的函數 以供調用。比如: 當用 double 類型使用函數模板時,編譯器通過對實參類型的推演,將 T 確定為 double 類型,然后產生一份專門處理 double 類型的代碼 ,對于字符類型也是如此。

2.4 函數模板的實例化

用不同類型的參數使用函數模板時 ,稱為函數模板的 實例化 。模板參數實例化分為: 隱式實例化 和顯式實例化 。

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

2. 顯式實例化:在函數名后的 <> 中指定模板參數的實際類型

2.5 模板參數的匹配原則

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

就比如一個模板的Add和一個自己實現的Add可以一起存在

然后:

void Test ()
{
      Add ( 1 , 2 );       // 與非模板函數匹配,編譯器不需要特化
      Add < int > ( 1 , 2 );   // 調用編譯器特化的 Add 版本
}

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

簡單說會先找自己實現的有沒有,沒有就去看模板能不能實例化一個。

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

2.6聲明定義分離

也可以聲明定義分離

不同的是模板參數聲明定義都要給

3. 類模板

3.1 類模板格式

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

這里就習慣用上class,上面的函數模板是typename

3.2 類模板的實例化

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

雖然有警告,但是為了測試,問題不大。我們可以發(fā)現這里是創(chuàng)建了兩個對象的,因為他們在各自的年齡和身高打印都是有所區(qū)別的(有無小數)

在這里 Student 這個類是一個模板,我們用這個模板創(chuàng)建了兩個對象 分別是張三和李四

注意:Student 不是具體的類,是編譯器根據被實例化的類型生成具體類的模具 PS:上面是用的Init,習慣還沒改過來,大家還是用構造函數比較好

3.3 類模板中函數放在類外進行定義時

需要加模板參數列表

4. 模板分離編譯

4.1 什么是分離編譯

一個程序(項目)由若干個源文件共同實現,而每個源文件單獨編譯生成目標文件,最后將所有目標文件鏈接起來形成單一的可執(zhí)行文件的過程稱為分離編譯模式。

4.2 模板的分離編譯

假如有以下場景,模板的聲明與定義分離開,在頭文件中進行聲明,源文件中完成定義:

// a.h
template<class T> 
T Add(const T& left, const T& right);
// a.cpp
template<class T> 
T Add(const T& left, const T& right) 
{
    return left + right; 
}
// main.cpp
#include"a.h"
int main()
{
    Add(1, 2);
    Add(1.0, 2.0);
    return 0; 
}

我們開始運行

問題:會出現鏈接錯誤。

原因:首先程序運行是要預處理,編譯匯編和鏈接。對于頭文件的內容,a.cpp .i .s .o模板都是空的,因為編譯器下不了手,不知道T是啥。(模板是在編譯階段處理,不是預處理)

main.cpp 里面因為只有聲明,所以call是不知道地址的

然后鏈接的時候,因為a.cpp是沒有生成對應的函數的(因為之前T不知道),所以鏈接的時候會發(fā)生鏈接錯誤。

簡單說就是編譯的時候經過模板的定義了但是因為T不知道所以不會生成對應的匯編代碼,導致最后main.cpp里面要調用的時候并沒有生成對應的函數所以會出現鏈接錯誤。

解決:

  • 放在一個名為 .hpp 的文件,也是就是這個文件是.h和.cpp的合體,寓意更好。直接.h也可以哈。(推薦)
  • 對于上面的原因對癥下藥,因為只有聲明沒有生成對應的定義,所以我們直接在 a.cpp 文件 顯示實例化指定在定義的下面加上:
template
int Add<int>(int& left, int& right);
template
double Add<double>(double& left, double& right);

為什么:

但是為什么放在一起就沒有鏈接錯誤了?

因為聲明和定義放在一起,調用函數的時候直接實例化call地址去了,所以不報錯并不是因為鏈接能找到,而是根本沒有去找,直接call地址了。

5. 缺省值與返回值

也可以有缺省值(半/全),但是必須是從右往左缺?。惐群瘮担驗閭鲄⑹菑淖笸覀鞯?/p>

也可以模板做返回值

6. 總結

優(yōu)點:

1. 模板復用了代碼,節(jié)省資源,更快的迭代開發(fā), C++ 的標準模板庫 (STL) 因此而產生

2. 增強了代碼的靈活性

缺陷:

1. 模板會導致代碼膨脹問題,也會導致編譯時間變長

2. 出現模板編譯錯誤時,錯誤信息非常凌亂,不易定位錯誤

到此這篇關于C++模板Template詳解及其作用介紹的文章就介紹到這了,更多相關C++模板內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 淺談幾種常見語言的命名空間(Namespace)

    淺談幾種常見語言的命名空間(Namespace)

    本文給大家簡單介紹了下幾種常見語言的命名空間的特性以及簡單示例,大家對比下,有需要的小伙伴可以參考下
    2016-03-03
  • 關于C++智能指針shared_ptr和unique_ptr能否互轉問題

    關于C++智能指針shared_ptr和unique_ptr能否互轉問題

    C++中的智能指針最常用的是shared_ptr和unique_ptr,C++新手最常問的問題是我從一個函數中拿到unique_ptr,但要轉成shared_ptr才能使用,要怎么轉換?同理是否能將shared_ptr轉換成unique_ptr,面對這些問題,跟隨小編一起看看吧
    2022-05-05
  • QT中進程的創(chuàng)建實現

    QT中進程的創(chuàng)建實現

    本文主要介紹了QT中進程的創(chuàng)建實現,詳細介紹了創(chuàng)建進程的整個過程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-08-08
  • C++實現圖形界面時鐘表盤代碼

    C++實現圖形界面時鐘表盤代碼

    這篇文章主要介紹了C++實現圖形界面時鐘表盤代碼,涉及坐標函數的應用及圖形界面程序設計,需要的朋友可以參考下
    2014-10-10
  • C語言線性表的鏈式表示及實現詳解

    C語言線性表的鏈式表示及實現詳解

    線性表的鏈式存儲特點則是用一組任意的存儲單元存儲線性表的數據元素。這組存儲單元既可以是連續(xù)的,也可以是不連續(xù)的。本文將詳解一下C語言線性表的鏈式表示及實現,感興趣的可以了解一下
    2022-07-07
  • C語言基礎知識變量的作用域和存儲方式詳細介紹

    C語言基礎知識變量的作用域和存儲方式詳細介紹

    這篇文章主要介紹了C語言基礎知識變量的作用域和存儲方式詳細介紹的相關資料,需要的朋友可以參考下
    2017-01-01
  • C語言實現簡單飛機大戰(zhàn)

    C語言實現簡單飛機大戰(zhàn)

    這篇文章主要為大家詳細介紹了C語言實現簡單飛機大戰(zhàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 詳解C++編程中的vector類容器用法

    詳解C++編程中的vector類容器用法

    vector是一個標準庫中的容器,使用時需要包含#include <vector>頭文件,也可以說vector是一個類模板而不是一種數據類型,對它的定義,需要指定類型,需要的朋友可以參考下
    2016-05-05
  • C程序中可怕的野指針圖文詳解

    C程序中可怕的野指針圖文詳解

    這篇文章主要給大家介紹了關于C程序中可怕的野指針的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C程序具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • 基于條件變量的消息隊列 說明介紹

    基于條件變量的消息隊列 說明介紹

    本篇文章小編為大家介紹,基于條件變量的消息隊列 說明介紹。需要的朋友參考一下
    2013-04-04

最新評論

秀山| 玉环县| 澎湖县| 冀州市| 合阳县| 南木林县| 通化市| 余江县| 衡山县| 盘山县| 宣汉县| 建宁县| 遂溪县| 盐城市| 皮山县| 绥化市| 扶沟县| 水富县| 自治县| 阿尔山市| 三亚市| 蒲江县| 图木舒克市| 临朐县| 曲靖市| 固安县| 华池县| 华安县| 湘乡市| 昌吉市| 苍山县| 涪陵区| 揭西县| 邢台县| 浮山县| 宝应县| 抚宁县| 柞水县| 岫岩| 宿迁市| 苗栗市|