模板

模板是泛型編程的基礎,即與類型無關的邏輯代碼。

利用模板機制可以顯著減少冗余信息,能大幅度地節約程序代碼,進一步提高面向對象程序的可重用性和可維護性。

模板是實現代碼重用機制的一種工具,它可以實現類型參數化;

模板分為函數模板和類模板。

為了使用函數名相同,參數不同,返回值可同可不同的函數時,我們起初用了重載的方式。

#include<iostream>
using?namespace?std;int?add(int?a,int?b)
{return?a+b;
}double?add(double?a,double?b)
{return?a+b;
}int?main()
{cout<<"ret1="<<add(1,2)<<endl;cout<<"ret2="<<add(2.3,3.0)<<endl;getchar();return?0;
}

wKioL1bvstuDo-moAAAPLD_E0cI751.png

但是運用重載的方式寫起來比較不方便,尤其是重載的函數較多時,為了解決這類問題,我們用函數模板來實現這種功能。

#include<iostream>
using?namespace?std;
template?<class?T>
T?add(const?T&?a,const?T&?b)
{cout<<"type:"<<typeid(a).name()<<endl;???//顯示類型return?a+b;
}int?main()
{cout<<"ret1="<<add(1,2)<<endl;//還可以顯示實例化,顯示指定T為int,即add<int>(1,2)cout<<"ret2="<<add(2.3,3.0)<<endl;???//add<double>(2.3,3.0)getchar();return?0;
}

wKioL1bvt4bxX-QPAAARBJCMVr0319.png

以上函數中函數參數類型都是相同的,當我們遇到形如:add(1,2.3);一個參數為int,一個參數為double型,此時我們可以這樣定義:

template?<class?T1,class?T2>
T?add(const?T1&?a,const?T2&?b)
{return?a+b;
}

當然,肯定有人會想,模板函數可以構成重載嗎?????j_0057.gif答案是肯定的。

#include<iostream>
using?namespace?std;int?add(int?a,int?b)
{return?a+b;
}double?add(double?a,double?b)
{return?a+b;
}
template?<class?T>
T?add(const?T&?a,const?T&?b)
{cout<<"type:"<<typeid(a).name()<<endl;?return?a+b;
}int?main()
{cout<<"ret1="<<add(1,2)<<endl;cout<<"ret2="<<add(2.3,3.0)<<endl;getchar();return?0;
}

當模板構成重載,調用add的函數時,它會先調用非模板類的函數,性能比較高;而模板函數內部還得調用,有推演過程判斷它是什么類型,效率上會有所降低。


2.模板類

對于普通函數來說,我們拿typedef重定義一個類型,當需要改的時候,需要將int改掉就可以了;

typedef?int?DataType;class?SEQLIST
{
private:DataType?*data;
};

而我們為了適應更多的類型,于是引入了模板類,我們這樣定義,體現了其高度復用的優勢:

template<class?T>
class?SeqList
{
private:T*?data;
};

寫一個模板類實現SeqList的動態順序表吧:

#include<iostream>
using?namespace?std;template?<class?T>
class?SeqList
{
public:SeqList():_data(NULL),_size(0),_capacity(0){}SeqList(const?SeqList<T>&?s);SeqList<T>&?operator=(const?SeqList<T>&?s);~SeqList(){if(_data?!=?NULL){delete[]?_data;}}void?CheckCapacity();void?PushBack(const?T&?d);void?PopBack();void?PushFront(const?T&?d);void?PopFront();void?Print();
private:T?*_data;int?_size;int?_capacity;
};
template?<class?T>
SeqList<T>::SeqList(const?SeqList<T>&?s)
{_data?=?new?T[s._size*sizeof(T)];int?i?=?0;for(i?=?0;i?<?s._size;?i++){_data[i]?=?s._data[i];}_size?=?s._size;_capacity?=?s._capacity;
}
template?<class?T>
SeqList<T>&?SeqList<T>::operator=(const?SeqList<T>&?s)
{int?i?=?0;if(this?==?&s){return?*this;}_size?=?s._size;_capacity?=?s._capacity;delete?_data;_data?=?new?T[_capacity];for(i?=?0;?i?<?_size;?i++){_data[i]?=?s._data[i];}return?*this;
}
template?<class?T>
void?SeqList<T>::CheckCapacity()
{if(_size?==?_capacity){T*?tmp?=?new?T[_capacity*2+3];//memcpy(tmp,_data,_size*sizeof(T));int?i?=?0;for(i?=?0;?i?<?_size;?i++){tmp[i]?=?_data[i];}delete[]?_data;_data?=?tmp;_capacity?=?_capacity*2+3;}
}
template?<class?T>
void?SeqList<T>::PushBack(const?T&?d)
{CheckCapacity();_data[_size]?=?d;_size++;
}
template?<class?T>
void?SeqList<T>::PopBack()
{CheckCapacity();_size--;
}template?<class?T>	
void?SeqList<T>::PushFront(const?T&?d)
{int?i?;CheckCapacity();	for(i?=?_size;?i?>?0;?i--){_data[i]?=?_data[i-1];}_data[0]?=?d;_size++;
}template?<class?T>
void?SeqList<T>::PopFront()
{int?i;CheckCapacity();for(i?=?0;?i?<?_size;?i++){_data[i]?=?_data[i+1];}_size--;
}
template?<class?T>
void?SeqList<T>::Print()
{int?i?=?0;for(i?=?0;?i?<?_size;?i++){cout<<_data[i]<<"?";}cout<<endl;
}int?main()
{SeqList<int>?seq;SeqList<int>?seq1;cout<<"seq:"<<endl;cout<<"尾插1234"<<endl;seq.PushBack(1);seq.PushBack(2);seq.PushBack(3);seq.PushBack(4);seq.Print();cout<<"尾刪"<<endl;seq.PopBack();seq.Print();cout<<"頭刪"<<endl;seq.PopFront();seq.Print();cout<<"seq2:"<<endl;SeqList<int>?seq2(seq);seq2.Print();cout<<"頭插567"<<endl;seq.PushFront(5);seq.PushFront(6);seq.PushFront(7);seq.Print();seq1?=?seq;cout<<"seq1:"<<endl;seq1.Print();getchar();return?0;
}

wKiom1byIpvxh_K5AAAVEIOLwCM902.png

模板就說到這里啦,有好的建議還希望大家提出來,歡迎來訪哦。i_f01.gifi_f01.gif

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

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

相關文章

C語言模擬實現標準庫函數之strstr()

strstr() strstr(str1,str2) 函數用于判斷字符串str2是否是str1的子串。如果是&#xff0c;則該函數返回str2在str1中首次出現的地址&#xff1b;否則&#xff0c;返回NULL。 char* my_strstr(const char* dest, const char* src) {char * str1 dest;char * str2 src;char …

linux-----強大的find

我又回來了。哈哈。今天我們來說一下linux中的另一個強大的find命令&#xff0c;灰常重要&#xff0c;灰常重要&#xff0c;灰常重要。顯而易見&#xff0c;find就是對某一個文件或者目錄的查找嘍。但是它的一個顯著的特點就是&#xff1a;一般放在后臺執行&#xff0c;從整個文…

C語言模擬實現標準庫函數之strchr()

strchr() 查找字符串s中首次出現字符c的位置 char * my_strchr(char *str1, char str2) {while (*str1 ! str2 && *str1 ! NULL){str1;}return str1; }int main() {char string[17];char *ptr, c r;strcpy(string, "Thisisastring");ptr my_strchr(string…

python 多人連接mysql 進行事務操作 對mysql加鎖與釋放鎖

python 多人連接mysql 對mysql進行事務操作 對mysql加鎖與釋放鎖 下面這個是user1代碼塊 # -*- coding: utf-8 -*- # user1 import pymysql import timeconn pymysql.connections.Connection(host"localhost", userdebian-sys-maint, passwordwL5wsDKDub4gT2EU…

C語言模擬實現標準庫函數之strcmp()

strcmp() C/C函數&#xff0c;比較兩個字符串 設這兩個字符串為str1&#xff0c;str2&#xff0c; 若str1str2&#xff0c;則返回零&#xff1b; 若str1<str2&#xff0c;則返回負數&#xff1b; 若str1>str2&#xff0c;則返回正數。 char * my_strcmp(char *key,…

linux之task_struct

每個進程中都有一個進程控制塊--PCB。PCB--維護進程相關的信息。然而&#xff0c;linux內核的進程控制塊就是task_struct結構體&#xff0c;它可以保存進程的信息。 所有運行在系統里的進程都以task_struct鏈表的形式存在內核里。 每個進程都將它的信息放在task_struct結構體…

python 用元類 type 實現對數據庫的ORM 映射

python 實現對數據庫的ORM 映射 如果使用pymysql 操作數據庫 不借助框架的話&#xff0c;頻繁寫sql語句, 的確比較麻煩 這里借助 type 元類 對 數據表類實現了 與mysql之間的 映射 直接上代碼 import pymysqldef conn_database_execute(sql_str):conn pymysql.connect(host…

C語言模擬實現標準庫函數之memcpy()

memcpy&#xff08;&#xff09; 1.如果我們需要對一個數組初始化&#xff0c;把數組的內容全部置0&#xff0c;那么能不能用strcpy() int main() {char arr1[10] { 0 };char arr2[10] " abcdefg ";strcpy(arr2, arr1);system("pause");return 0; } 我…

說說堆及堆排序

堆&#xff1a;是一種數組對象&#xff0c;它可以被看成是一種二叉樹結構。 我們把堆的二叉樹存儲方式分為兩種&#xff1a;即大堆和小堆。那么問題來了&#xff0c;什么大堆&#xff1f;什么是小堆&#xff1f; 大堆&#xff1a;讓每個父節點的值都大于孩子節點的值。 小堆…

運算符優先級 速查表

運算符優先級 優先級【高到低】&#xff1a; 第一級&#xff1a; 圓括號【&#xff08;&#xff09;】、下標運算符【[]】、分量運算符的指向結構體成員運算符【->】、結構體成員運算符【.】 第二級&#xff1a; 邏輯非運算符【!】、按位取反運算符【~】、自增自減運…

linux--幾種常見的進程調度算法

進程調度&#xff1a;在操作系統中調度是指一種資源分配&#xff0c;因而調度算法是指:根據系統的資源分配策略所規定的資源分配算法。操作系統管理了系統的有限資源&#xff0c;當有多個進程(或多個進程發出的請求)要使用這些資源時&#xff0c;因為資源的有限性&#xff0c;必…

指針數組和數組指針和函數指針

文章目錄1.指針數組和數組指針1.int *p1[10];2.int (*p2)[10];2.函數指針char *(*fun1)(char * p1,char *p2)函數指針的概念函數指針的作用&#xff1a;例子1 .調用方式例子2&#xff1a;&#xff08;帶注釋&#xff09;例子33.做題的小技巧1.指針數組和數組指針 1.int *p1[10…

使用虛擬環境virtualenv 創建虛擬環境出現PermissionError: [Errno 13] Permission denied:

使用虛擬環境virtualenv 創建虛擬環境出現PermissionError: [Errno 13] Permission denied: 原因&#xff1a;虛擬環境安裝的目錄所屬用戶非當前用戶 解決辦法&#xff1a;將目錄及其文件的所有者改為當前用戶 解決命令&#xff1a;sudo chown -R 當前用戶 待更改用戶的目錄/ …

linux之父子進程的輸出

首先&#xff0c;我們來回憶一下父進程與子進程&#xff0c;前幾節講了如何創建子進程&#xff0c;像這樣的&#xff0c;pid_t id fork(); 這樣我們就創建好了一個子進程&#xff0c;然而fork()函數的返回值是什么呢&#xff1f;這里要記住&#xff1a;子進程返回0&#xff0c…

linux---談談vfork和fork的區別及exit與return

fork()&#xff1a;創建子進程的函數&#xff0c;是大家比較熟悉的吧。pid_t id fork(); 這里的vfork();也是創建子進程的函數。現在我們來剖析一下它們吧。 第一例&#xff1a; 先看一個fork()的例子哦。 對于fork()而言&#xff0c;創建子進程成功后直接打印出父子進程執…

在MySQL數據庫建立多對多的數據表關系

轉載自 https://blog.51cto.com/13145200724/1370753

C語言模擬實現標準庫函數之qsort()

qsort 編譯器函數庫自帶的快速排序函數。 void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 參數解釋&#xff1a; void*base-待排序數組首地址size_t num-數組中待排序元素數量size_t width-各元素的占用空間大小int(__cde…

django contrib 包簡介

轉自 https://www.cnblogs.com/tianboblog/p/6955297.html

linux之管道

管道&#xff08;PIPE&#xff09;是linux中一個重要的通信方式&#xff0c;在進程中&#xff0c;我們通過從一個進程中讀取到的數據轉到另一個進程中的寫數據中&#xff0c;這時就要有不同的進程之間共享同一份資源&#xff0c;就是所謂的進程間通信。由于進程的特點是資源獨占…

把student a am i 變成 i am a student(兩種方法)

文章目錄#student a am i 變成 i am a student##方法1&#xff1a;指針#include <stdlib.h> #include <stdio.h> #include <string.h>void fanw(char *l, char *r) {char* left l;char* right r;char temp;while (left < right){temp *left;*left *ri…