主頁 >  其他 > C++進階-1-模板基礎(函式模板、類模板)

C++進階-1-模板基礎(函式模板、類模板)

2022-05-06 08:03:59 其他

C++進階 模板

1.1 函式模板

  1 #include<iostream>
  2 using namespace std;
  3 
  4 // 模板
  5 
  6 // 模板的簡單實體
  7 // 要求:
  8 //        1.利用函式模板封裝一個排序函式,可以對不同資料型別陣列進行排序
  9 //        2.排序規則由大到小,排序演算法為:選擇排序
 10 //        3.分別利用char陣列和int陣列進行測驗
 11 
 12 // 交換函式模板
 13 template<class T>
 14 void mySwap(T& a, T& b) {
 15     T temp = a;
 16     a = b;
 17     b = temp;
 18 }
 19 
 20 // 排序演算法模板
 21 template<class T>  // 也可以寫typename
 22 void mySort(T arr[], int len) {
 23     // 選擇排序
 24     for (int i = 0; i < len; i++) {
 25         int max = i;  // 認定最大值下標
 26         for (int j = i + 1; j < len; j++) {
 27             // 認定的最大值 比 遍歷出的最大值 要小,說明 j 下標的元素才是真正的最大值
 28             if (arr[max] < arr[j]) {
 29                 max = j;  // 更新最大值下標
 30             }
 31         }
 32         if (max != i) {
 33             // 交換下標為max和i的元素
 34             mySwap(arr[max], arr[i]);
 35         }
 36     }
 37 }
 38 
 39 // 列印數字內容模板
 40 template<class T>
 41 void printArray(T arr[], int len) {
 42     for (int i = 0; i < len; i++) {
 43         cout << arr[i] << " ";
 44     }
 45     cout << endl;
 46 }
 47 
 48 
 49 void test01() {
 50 
 51     // 測驗陣列 char型別
 52     char charArr[] = "badcfe";
 53     int num_charArray = sizeof(charArr) / sizeof(char);
 54     mySort(charArr, num_charArray);
 55     printArray(charArr, num_charArray);
 56 
 57     // 測驗陣列 int型別
 58     int intArray[] = { 1, 3, 2, 6, 4, 5, 7 };
 59     int num_int = sizeof(intArray) / sizeof(int);
 60     mySort(intArray, num_int);
 61     printArray(intArray, num_int);
 62 }
 63 
 64 int main() {
 65 
 66     test01();
 67 
 68     system("pause");
 69 
 70     return 0;
 71 }
 72 
 73 // 總結
 74 // C++除了面向物件編程思想外,還有 泛型編程 以及 STL 技術
 75 // 
 76 // 模板:建立通用的模具,大大提高代碼的復用性
 77 // 模板不可以直接使用,它只是一種框架
 78 // 模板的通用并不是萬能的
 79 // 
 80 // 模板分為:函式模板與類模板
 81 // 
 82 // 
 83 // 函式模板:
 84 // 
 85 // 模板的作用:建立一個通用函式,其函式回傳值型別和形參型別都可以不具體制定,用一個虛擬的型別來表示
 86 // 語法:
 87 //        template<typename T>  // typename也可以寫成 class
 88 //        函式生命或定義
 89 //    解釋:T 通用的資料型別,名稱可以替換,通常為大寫字母
 90 // 
 91 // 函式模板的使用方式有兩種:自動型別推導、顯示指定型別
 92 // 
 93 // 模板注意事項:
 94 //        1.自動型別推導方式,必須推匯出一致的資料型別T,才可以使用
 95 //        2.模板必須要確定出T的資料型別,才可以使用
 96 // 
 97 // 普通函式與函式模板的區別
 98 //    1.普通函式呼叫可以發生自動型別轉換(隱式轉換);
 99 //    2.函式模板呼叫時,如果利用自動型別推導,不會發生隱式型別轉換
100 //    3.如果利用顯示指定型別的方式,可以發生隱式轉換;
101 // 
102 //        所以,建議使用顯示指定型別的方式,呼叫函式模板,因為可以自己確定通用型別
103 // 
104 // 普通函式與函式模板的呼叫規則
105 //    1.如果函式模板和普通函式都有可以實作,編譯器會優先呼叫普通函式
106 //    2.可以通過空模板引數串列來強制呼叫函式模板(加<>)
107 //    3.函式模板也可以發生多載
108 //    4.如果利用函式模板可以產生更好的匹配,優先呼叫函式模板
109 // 
110 //        所以,既然提供了函式模板,就最好不要再提供普通函式了,否則出現二義性
111 // 
112 // 模板的局限性
113 //    1.模板的通用型不是萬能的
114 //        利用具體化的模板,可以解決自定義型別的通用化
115 //        學習模板不是為了寫模板,而是在STL能夠運用系統提供的模板
116 // 
117  

 

1.2 類模板

#include<iostream>
#include<string>
using namespace std;

// 類 模板


// 示例1
//template<class Nametype, class Agetype>

// 類模板可以有默認引數
template<class Nametype, class Agetype = int>
class Person1 {
public:

    Person1(Nametype name, Agetype age) {
        this->m_Name = name;
        this->m_Age = age;
    }

    void showPerson() {
        cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
    }

    //string m_Name;
    //int m_Age;

    Nametype m_Name;
    Agetype m_Age;

};

void test01() {

    //Person p1("Tom", 19);  // 報錯,無法自動推導型別
    //Person1<string, int> p1("Tom", 19);
    Person1<string> p1("Tom", 19);

    p1.showPerson();

}

// 示例2
// 類模板物件做函式引數,三種傳入方式

template<class T1, class T2>
class Person2
{
public:
    Person2(T1 name, T2 age) {
        this->m_Name = name;
        this->m_Age = age;
    };

    void showPerson() {
        cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
    }

    T1 m_Name;
    T2 m_Age;

};

// 1.指定傳入型別
void printPerson1(Person2<string, int>& p) {
    p.showPerson();
}

// 2.引數模板化
template<class T1, class T2>
void printPerson2(Person2<T1, T2>& p) {
    p.showPerson();
    // 看一下編譯器推匯出的型別
    cout << "T1的型別為:" << typeid(T1).name() << endl;
    cout << "T2的型別為:" << typeid(T2).name() << endl;
}

// 3.整個類模板化
template<class T>
void printPerson3(T& p) {
    p.showPerson();
    cout << "T的型別為:" << typeid(T).name() << endl;
}

void test02() {
    Person2<string, int>p("小明", 20);
    
    // 1.指定傳入型別(最常用)
    printPerson1(p);

    // 2.引數模板化
    printPerson2(p);

    // 3.整個類模板化
    printPerson3(p);
}


// 示例3 類模板與繼承
template<class T>
class Base {
    T m;
};

// class Son:pubic Base  // 錯誤,C++編譯需要給子類分配記憶體,必須知道父類中T的型別才可以向下繼承
class Son1 :public Base<int> {  // 必須指定一個型別

};

// 如果想靈活制定出父類中T的型別,子類也需要變為模板
template<class T1, class T2>
class Son2 :public Base<T2> {
public:
    Son2() {
        cout << "T1的型別為:" << typeid(T1).name() << endl;
        cout << "T2的型別為:" << typeid(T2).name() << endl;
    }
    T1 obj;
};

void test03() {

    Son1 s1;

    Son2<int, char> s2;
}

// 示例4 類模板成員函式類外實作
template<class T1, class T2>
class Person4
{
public:
    Person4(T1 name, T2 age);  // 類內宣告
    //{
    //    this->m_Name = name;
    //    this->m_Age = age;
    //};

    void showPerson();  // 類內宣告
    //{
    //    cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
    //}

    T1 m_Name;
    T2 m_Age;

};

// 類外實作
template<class T1, class T2>
Person4<T1, T2>::Person4(T1 name, T2 age) {
    this->m_Name = name;
    this->m_Age = age;
}

template<class T1, class T2>
void Person4<T1, T2>::showPerson() {
    cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
}


void test04() {
    Person4<string, int> p4("張三", 100);
    p4.showPerson();
}


int main() {

    // 類模板初識
    //test01();

    // 類模板物件做函式引數
    //test02();

    // 類模板與繼承
    //test03();

    // 類模板成員函式類外實作
    test04();

    system("pause");

    return 0;
}

// 總結
// 
// 模板分為:函式模板與類模板
// 
// 
// 類模板:
// 
// 類模板作用:建立一個通用類,類中的成員 資料型別可以不具體制定,用一個虛擬型別來代表
// 
// 語法:
//        template<typename T>  // typename可以寫成 class,與typename沒啥具體區別
////    
// 類模板與函式模板區別:
//    1.類模板沒有自動型別推導的使用方式,所以必須指定
//    2.類模板在模板引數串列中可以有默認引數
// 
// 類模板中成員函式的創建時機
//    1.普通類中的成員函式一開始就可以創建
//    2.類模板中的成員函式在呼叫時才開始創建
// 
// 類模板物件做函式引數
//    類模板實體化出物件,向引數傳參
//    三種傳參方式:
//        1.制定傳入型別    直接顯示物件的資料型別(最常用)
//        2.引數模板化    將物件中的引數變為模板進行傳遞
//        3.整個類模板化    將這個物件型別 模板化進行傳遞
// 
// 類模板與繼承
//    1.當子類繼承的父類是一個類模板時,子類在宣告的時候,要指定出父類T的型別
//    2.如果不指定,編譯器無法給子類分配記憶體
//    3.如果想靈活制定出父類中T的型別,子類也需要變為模板
// 
// 類模板的成員函式可以類外實作(類內宣告,類外實作)
//    需要添加:1.作用域;2.引數模板/引數模板串列
// 
// 類模板份檔案撰寫
//    問題:類模板中成員函式創建時機是在 呼叫階段 ,導致分檔案撰寫時鏈接不到
// 
//    解決:
//        方式1:直接包含.cpp源檔案
//        方式2:將宣告和實作寫到同一個檔案中,并更改后綴名為.hpp hpp是約定的名稱,并不強制
// 
// 類模板與友元
//    全域函式類內實作:直接在類內宣告友元即可(建議使用類內實作)
//    全域函式類外實作:需要提前讓解釋器知道全域函式的存在
//        1.加一個空模板的引數串列<>
//        2.把代碼剪切到代碼檔案的最上方,讓編譯器先看到
//        3.加入類的宣告,提前讓編譯器看到模板類
// 

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/469725.html

標籤:其他

上一篇:Unity實作簡單的物件池

下一篇:MatrixOne邀你參與2022開源之夏

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more