【C++】模板入门 超、凢脫俗 2022-10-30 09:29 124阅读 0赞 ### 文章目录 ### * 1. 泛型编程 * 2. 函数模板 * * 2.1 函数模板概念 * 2.2 函数模板格式 * 2.3 通用的交换函数 * 2.4 反汇编代码验证 * 2.5 不同数据类型的函数模板 * 2.6 隐式实例化与显式实例化 * 2.7 模板参数的匹配原则 * 3. 类模板 * * 3.1 类模板的定义格式 * 3.2 使用类模板实现动态类型顺序表 # 1. 泛型编程 # > 如何实现一个**通用的交换函数**呢? > > 你可能首先会想到使用**函数重载**,使用函数重载虽然可以实现,但是它有以下的缺点: > > 1. 重载的函数代码重复率较高,当出现新类型的时候,就需要增加对应类型的重载函数 > 2. 代码的可维护性较低,一个出错可能所有的重载均出错 * 最佳的做法还是告诉编译器一个模板。当编译器遇到**不同的数据类型**时根据该**模板**自动生成相同功能的代码 * 在C++编程思想中有一种思想叫做**泛型编程**,即编写与类型无关的通用代码,这是一种**代码复用**的手段,模板是泛型编程的基础 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70] # 2. 函数模板 # ## 2.1 函数模板概念 ## > 函数模板就代表了完成同一个功能的函数家族,该函数模板与数据类型无关,在使用该函数时,根据实参的数据类型产生特定数据类型的函数 ## 2.2 函数模板格式 ## > 在函数前加上下面格式的代码: > > template<typename T1, typename T2,......,typename Tn> ## 2.3 通用的交换函数 ## template<typename T> void Swap( T& left, T& right) { T temp = left; left = right; right = temp; } > 注意:typename是用来定义模板的关键字,也可以使用class 在编译器**编译阶段**,对于模板函数的使用,编译器需要**根据传入的实参类型**来**推演生成对应类型的函数**以供调用。 比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此 ## 2.4 反汇编代码验证 ## > 由汇编代码看出:编译器根据**数据类型**按照**模板函数**自动生成了**相应的实例化函数** #include <iostream> using namespace std; template<typename T> T add(T a, T b) { return a + b; } int main() { add(1, 2); add(1.0, 2.0); add('1', '2'); cout << endl; return 0; } ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 1] ## 2.5 不同数据类型的函数模板 ## template<typename T, class S> void fun(T a, S b) { // TO DO } ## 2.6 隐式实例化与显式实例化 ## `隐式实例化`:让**编译器**根据**实参**`推演`**模板参数**的**实际类型** add(1,2); //隐式实例化 `显式实例化`:在函数名后的`<>`中**指定**模板参数的**实际类型** add<int>(1,2); //显式实例化 ## 2.7 模板参数的匹配原则 ## > 1. 当类模板和类型实例化函数同时出现时,并且传参使用的是隐式实例化,编译器**首先匹配函数**而不是使用模板实例化函数 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 2] > 1. 当类模板和类型实例化函数同时出现时,并且传参使用的是显示实例化,编译器**首先使用模板函数** ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 3] # 3. 类模板 # ## 3.1 类模板的定义格式 ## template<class T1, class T2, class T3, ..., class Tn> class ClassName{ //TO DO }; ## 3.2 使用类模板实现动态类型顺序表 ## > 在实例化类时需传递数据类型 template<class T> class SeqList { private: T* dataArray; size_t capacity; size_t size; public: //构造函数与析构函数 SeqList(size_t capacity = 10) :capacity(capacity), dataArray(new T[capacity]), size(0){ } SeqList(const SeqList<T>& s) { capacity = s.capacity; dataArray = new T(capacity); for (size = 0; size < s.size; size++) dataArray[size] = s[size]; } SeqList<T>& operator=(const SeqList<T>& s) { capacity = s.capacity; dataArray = new T(capacity); for (size = 0; size < s.size; size++) dataArray[size] = s[size]; } T& operator[](const size_t index) { if (index < size && index >= 0) { return dataArray[index]; } else { return -1; } } ~SeqList() { if (dataArray) { delete[] dataArray; capacity = 0; size = 0; } } //具体方法 size_t getSize() const; size_t getCapacity() const; bool isEmpty()const; void push_back(const T& data); void pop_back(); T front(); }; // 具体方法的类外实现 template<class T> size_t SeqList<T>::getSize() const { return size; } template<class T> size_t SeqList<T>::getCapacity() const { return capacity; } template<class T> bool SeqList<T>::isEmpty()const { return 0 == size; } template<class T> void SeqList<T>::push_back(const T& data) { if (size < capacity)//空间足够 { dataArray[size] = data; size++; } else//空间不够 { return; } } template<class T> void SeqList<T>::pop_back() { if (isEmpty()) { return; } size--; } template<class T> T SeqList<T>::front() { return dataArray[size - 1]; } [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70]: /images/20221024/dacbb5e49caf499e9eda05a81712ced7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 1]: /images/20221024/21a2aa488eae4ba984b1d1e4e19bfe83.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 2]: /images/20221024/4da0095b34274b81a187ec501cbceab5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTQzNzAyMg_size_16_color_FFFFFF_t_70 3]: /images/20221024/bb92d92b48e34a75b0d8c41f7f8d93b0.png
相关 C++ STL 标准模板库介绍与入门 录 1、概述 1.1、C++ 标准库 1.2、Boost库 2、STL 版本 2.1、HP 原始版本 缺乏、安全感/ 2024年04月17日 11:02/ 0 赞/ 89 阅读
相关 C++ 模板: 函数模板 文章目录 C++ 模板 函数模板 1. 模板的概念 2. 函数模板 2.1 函数模板语法 2.2 秒速五厘米/ 2022年12月30日 12:55/ 0 赞/ 271 阅读
相关 C++模板 函数模板 函数模板,是可以创建一个通用的函数,可以支持多种形参。 用关键字 `template` 来定义, 在函数模板中,数据的值和类型都被参数化了,发生函数调用时编 你的名字/ 2022年12月23日 00:43/ 0 赞/ 124 阅读
相关 【C++】模板入门 文章目录 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 通用的交换函数 超、凢脫俗/ 2022年10月30日 09:29/ 0 赞/ 125 阅读
相关 C++模板 C++模板 ①模板是实现代码重用机制的一种工具。就是根据参数类型生成函数和类的机制。它可以分成两类:一是函数模板,二是类模板,他们允许用户构造模板函数,模板类。 也可称通用 谁借莪1个温暖的怀抱¢/ 2022年09月17日 11:20/ 0 赞/ 147 阅读
相关 c++模板 1定义函数模板 include<stdexcept> include <sstream> include <map> using namesp 水深无声/ 2022年08月21日 08:55/ 0 赞/ 165 阅读
相关 C++入门(18):模板 C++入门(18):模板 模板( template )、 STL(标准模板库) 在泛型编程技术里,仍需要编写自己的函数和类,但不必限定它们所使用的数据类型(int、d ゝ一世哀愁。/ 2022年08月19日 13:24/ 0 赞/ 52 阅读
相关 C++:模板 http://[blog.csdn.net/pipisorry/article/details/72353250][blog.csdn.net_pipisorry_articl 逃离我推掉我的手/ 2022年06月16日 13:59/ 0 赞/ 196 阅读
相关 c++模板 1.类模板及其(全)特化和偏特化 模板特化是通过"给模板中的所有模板参数一个具体的类"的方式来实现的.而模板偏特化则是通过"给模板中的部分模板参数以具体的类,而留下剩余的模板 红太狼/ 2022年05月17日 03:49/ 0 赞/ 158 阅读
相关 C++模板 文一:[/images/20220319/2dfa5cca396940129714244edcacafad.png][http_www.cnblogs.com_CaiNiaoZ Bertha 。/ 2022年03月19日 13:30/ 0 赞/ 238 阅读
还没有评论,来说两句吧...