C++ 模板 冷不防 2024-03-25 12:45 78阅读 0赞 **C++入门系列文章:** [C++、STL常用容器][C_STL] [C++、STL – 函数对象、常用算法][C_STL _] **前言:** > 学习模板并不是为了写模板,而是在STL能够运用系统提供的模板 #### 函数模板: #### 建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个**虚拟的类型**来代表。 语法: template<typename T> //声明一个模板,告诉编译器后面代码中紧跟的T不要报错,T是一个通用数据类型 解释: * template :声明创建模板 * typename :表面其后面的符号是—种数据类型,可以用 **class** 代替 * T :通用的数据类型,名称可以替换,通常为大写字母 //交换整型函数 void swapInt(int& a, int& b){ int temp = a; a = b; b = temp; } //交换浮点型函数 void swapDouble(double& a,double& b){ double temp = a; a = b; b = temp; } //利用模板提供通用的交换函数 template<typename T> void mySwap(T& a,T& b)( T temp = a; a = b; b = temp; } void test01(){ int a = 10; int b - 20; //利用模板实现交换 //1、自动类型推导 mySwap(a, b); //2、显示指定类型,建议使用此方式 mySwap<int>(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl; } int main() { test01(); system("pause"); return 0; } > 自动类型推导,必须推导出一致的数据类型T,才可以使用; 模板必须要确定出T的数据类型,才可以使用。 / /2、模板必须要确定出T的数据类型,才可以使用 template<class T> void func() { cout <<"func 调用"<< endl; ) void test02() { func<int>();//不管T用到没用到,都要先确定 } 普通函数与函数模板调用规则 1. 如果函数模板和普通函数都可以调用,优先调用普通函数; 2. 可以通过空模板参数列表强制调用函数模板; 3. 函数模板可以发生函数重载; 4. 如果函数模板可以产生更好的匹配,优先调用函数模板。 > 既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性 #### 类模板 #### 类模板作用: * 建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚拟的类型来代表。 语法: template<typename T> 类 解释: * template :声明创建模板 * typename :表面其后面的符号是一种数据类型,可以用class代替 * T :通用的数据类型,名称可以替换,通常为大写字母 //类模板 template<class NameType,class AgeType> class Person { public: Person (NameType name,AgeType age){ this->m_Name = name ; this->m_Age = age; } NameType m_Name; AgeType m_Age; }; void test01() { //Person p("孙悟空", 999l); 错误,无法用自动类型推导 Person<string, int> p1("孙悟空", 999l); //正确,只能用显示指定类型 } > 类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板 类模板与函数模板区别主要有两点: 1. 类模板**没有自动类型推导**的使用方式 2. 类模板在模板参数列表中可以有 **默认参数** template<class NameType, class AgeType = int> //默认参数 Person<string> p ("猪八戒", 999);//有默认参数,就可以不用显示指定 类模板中成员函数和普通类中成员函数**创建时机**是有区别的: * 普通类中的成员函数一开始就可以创建 * 类模板中的成员函数在 **调用时才创建** ##### 类模板对象做函数参数 ##### 类模板实例化出的对象,向函数传参的方式,—共有三种传入方式: 1. 指定传入的类型:直接显示对象的数据类型(广泛使用) 2. 参数模板化:将对象中的参数变为模板进行传递 3. 整个类模板化:将这个对象类型模板化进行传递 ##### 当类模板碰到继承时,需要注意一下几点: ##### * 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型 * 如果不指定,编译器无法给子类分配内存 * 如果想灵活指定出父类中T的类型,子类也需变为类模板 //类模板与继承 template<class T> class Base { T m; }; //class Son :public Base //错误,必须要知道父类中的T类型,才能继承给子类 class Son : public Base<int> { }; //如果想灵活指定父类中T类型,子类也需要变类模板 template<class T1, class T2> class Son2 : public Base<T2>{ T1 obj; }; void test02() { Son2<int,char> S2;//指定 T1 = int ,T2 = char } ##### 类模板成员函数类外实现 ##### > 类模板中成员函数类外实现时,需要加上模板参数列表 #include <string> //类模板中成员函数类外实现 template<class T1, class T2> class Person { public: //成员函数类内声明 Person(T1 name, T2 age); void showPerson(); public: T1 m_Name; T2 m_Age; }; //构造函数类外实现 template<class T1, class T2> Person<T1, T2>::Person(T1 name, T2 age){ this->m_Name = name; this->m_Age = age; } //成员函数类外实现 template<class T1, class T2> void Person<T1, T2>::showPerson() { cout << "姓名:"<< this->m_Name << "年龄:"<< this->m_Age << endl; } ##### 类模板分文件编写 ##### **问题:** * 类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到 **解决:** * 解决方式1:直接包含.cpp源文件;(很少这样做!) * 解决方式2∶将**声明**和**实现**写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制。(主流、常用) ##### 类模板与友元 ##### 全局函数类内实现 : 直接在类内声明友元即可 全局函数类外实现 :需要**提前**让编译器知道**全局函数的存在** > 建议全局函数做类内实现,用法简单,而且编译器可以直接识别 //提前让编译器知道Person类存在 template<class T1,class T2> class Person; //全局函数类外实现 template<class T1, class T2> friend void printPerson2(Person<T1, T2> p) { cout<<"类外实现: 姓名:" << p.m_Name << "年龄:" << p.m_Age << endl; } template<class T1, class T2> class Person { //全局函数类内实现 friend void printPerson(Person<T1, T2> p) { cout<<"姓名:" << p.m_Name << "年龄:" << p.m_Age << endl; } //全局函数类外实现 //加空模板的参数列表 //如果全局函数是类外实现,需要让编译器提前知道这个函数的存在 friend void printPerson2<>(Person<T1, T2> p); public: Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } private:| T1 m_Name; T2 m_Age; } //1、全局函数在类内实现 void test01() { Person<string, int> p("Tom", 20); printPerson(p); } ##### 注:仅供学习参考,如有不足,欢迎指正! ##### [C_STL]: https://blog.csdn.net/weixin_43412762/article/details/129561216 [C_STL _]: https://blog.csdn.net/weixin_43412762/article/details/129671606
相关 C++ 模板 C++入门系列文章: [C++、STL常用容器][C_STL] [C++、STL – 函数对象、常用算法][C_STL _] 前言: > 学习模板并不是为了写模板,而 冷不防/ 2024年03月25日 12:45/ 0 赞/ 79 阅读
相关 C++模板 C++模板 1. 模板概念 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 客官°小女子只卖身不卖艺/ 2023年09月28日 12:09/ 0 赞/ 20 阅读
相关 C++模板 1. 为什么要使用模板? 1. 假如设计一个求两参数最大值的函数,在实践中我们可能需要定义四个函数: ![format_png][] 2. 这些函数 怼烎@/ 2023年05月31日 06:56/ 0 赞/ 17 阅读
相关 C++ 模板: 函数模板 文章目录 C++ 模板 函数模板 1. 模板的概念 2. 函数模板 2.1 函数模板语法 2.2 秒速五厘米/ 2022年12月30日 12:55/ 0 赞/ 274 阅读
相关 C++模板 函数模板 函数模板,是可以创建一个通用的函数,可以支持多种形参。 用关键字 `template` 来定义, 在函数模板中,数据的值和类型都被参数化了,发生函数调用时编 你的名字/ 2022年12月23日 00:43/ 0 赞/ 126 阅读
相关 C++模板 C++模板 ①模板是实现代码重用机制的一种工具。就是根据参数类型生成函数和类的机制。它可以分成两类:一是函数模板,二是类模板,他们允许用户构造模板函数,模板类。 也可称通用 谁借莪1个温暖的怀抱¢/ 2022年09月17日 11:20/ 0 赞/ 149 阅读
相关 c++模板 1定义函数模板 include<stdexcept> include <sstream> include <map> using namesp 水深无声/ 2022年08月21日 08:55/ 0 赞/ 167 阅读
相关 C++:模板 http://[blog.csdn.net/pipisorry/article/details/72353250][blog.csdn.net_pipisorry_articl 逃离我推掉我的手/ 2022年06月16日 13:59/ 0 赞/ 199 阅读
相关 c++模板 1.类模板及其(全)特化和偏特化 模板特化是通过"给模板中的所有模板参数一个具体的类"的方式来实现的.而模板偏特化则是通过"给模板中的部分模板参数以具体的类,而留下剩余的模板 红太狼/ 2022年05月17日 03:49/ 0 赞/ 160 阅读
相关 C++模板 文一:[/images/20220319/2dfa5cca396940129714244edcacafad.png][http_www.cnblogs.com_CaiNiaoZ Bertha 。/ 2022年03月19日 13:30/ 0 赞/ 243 阅读
还没有评论,来说两句吧...