1、模块的引入

1.1、示例代码

#include <iostream>
#include <string>using namespace std;//用template声明T是模板类
template <typename T>
T add(T a, T b)
{return a + b;
}int main(void)
{//给add函数传入int类型,此时T就会被替换成int类型:int add(int a, int b)int var1 = add(11, 22);//给add函数传入double 类型,此时T就会被替换成double类型:double add(double a, double b)double var2 = add(11.11, 22.22);cout << "var1=" << var1 << ", var2=" << var2 << endl;return 0;
}

1.2、代码分析

root@ubuntu:# ./app
var1=33, var2=33.33

(1)用template声明T是模板类型,也就是表示T是泛指数据类型,不是具体的数据类型;
(2)add的参数用T来表示,说明add函数的传参和返回值都是模板类型,需要在调用add函数时来指定;
(3)用模板来定义add函数使得代码更简洁,如果不使用模板则需要定义多个不同传参类型的add函数来实现函数重载,以适配不同类型的变量;

2、模板的优劣势

(1)优点:使用模板可以写出更加抽象和简洁的代码;可以将运算逻辑相同只有数据类型不同的函数用模板进行抽象,一个模板函数实现多个重载函数的效果,比如上面的add函数;
(2)缺点:模板并不是必须,不使用模板一样可以实现同样的效果,使用模板需要额外学习和掌握模板编程的规则;
总结:模板编程是用复杂度换取劳动量,用模板写代码抽象度更高,代码简洁,但是对程序员的要求也更高;

3、模板的原理分析

(1)模板编程可以写出类型无关的函数和类,代码更抽象,只关注逻辑部分,编译器在编译模板类/函数时不会指定具体的数据类型;
(2)在使用模板类/函数时,需要指定模板参数的类型,编译器会替换模板参数为具体的类;
(3)在最终编译成的代码中,是没有模板类/函数的,因为编译器已经在用到模板函数/类的地方都替换成了具体的函数类型;
(4)模板是编译器提供的机制,实现了编译时的多态;

4、模板实现运算符重载函数

4.1、示例代码

#include <iostream>
#include <string>using namespace std;// 定义模板类
template <typename T> class People
{private:T age;public:People(){};People(T a):age(a){};// 运算符重载 +  -     c = a + b;People<T> operator+(People<T> &other);// 运算符重载+=     a += b;  等价于 a = a + b;People<T> operator+=(People<T> &other);void print(void);
};//友元函数进行运算符重载
template <typename T> People<T> People<T>::operator+(People<T> &other)
{People<T> tmp;tmp.age = this->age + other.age;return tmp;
}//友元函数进行运算符重载
template <typename T> People<T> People<T>::operator+=(People<T> &other)
{this->age += other.age;return *this;
}template <typename T> void People<T>::print(void)
{cout << "age = " << this->age << endl;
}int main(void)
{//在定义People类的对象时需要指定模板类的具体类型People<string> a("hello ");People<string> b("word !");People<string> c("");a += b;a.print();//在定义People类的对象时需要指定模板类的具体类型People<int> d(4);People<int> e(6);People<int> f(0);f = d + e;f.print();return 0;
}

4.2、代码分析

[root#]$ ./app
age = hello word !
age = 10

(1)用友元函数对People类的"+、+="运算符进行重载,并且重载函数也是带模板类的;
(2)在定义People类的对象时,需要指定模板类T的具体类型,这个类型也会传给运算符重载函数,这样类和重载函数的模板类T都被具体的数据类型所代替;
(3)友元函数参考博客:https://blog.csdn.net/weixin_42031299/article/details/127699941;
(4)运算符重载参考博客:https://blog.csdn.net/weixin_42031299/article/details/127593164;

5、模板类的继承

5.1、示例代码

#include <iostream>
#include <string>using namespace std;// 定义模板类,作为父类
template <typename U1, typename U2> class People
{public:U1 x1;       // x1是doubleU2 x2;      // x2是intPeople(){};People(U1 a, U2 b):x1(a),x2(b){};};// Man类里T1对应int,T2对应double
//把T1和T2模板参数传给父类People,去初始化父类的模板参数
template <typename T1, typename T2> class Man:public People<T2, T1>
{public:T1 y1;       // T1 int T2 y2;        // T2 doubleMan(){};Man(T1 a, T2 b):y1(a),y2(b){};// 4个参数,顺序:按照y1 y2 x2 x1//T1传给People的U2,T2传给People的T1Man(T1 a1, T2 a2, T1 b1, T2 b2):People<T2,T1>(b2, b1),y1(a1),y2(a2){};};int main(void)
{//此时Man类的T1对应int,T2对应doubleMan<int,double> m1(4, 5.5, 6, 7.7);        // y1=4, y2=5.5   x1=7.7, x2=6cout << "x1 = " << m1.x1 << ", x2 = " << m1.x2 << endl;cout << "y1 = " << m1.y1 << ", y2 = " << m1.y2 << endl;return 0;
}

5.2、代码分析

[root#]$ ./app
x1 = 7.7, x2 = 6
y1 = 4, y2 = 5.5

(1)首先需要知道在定义模板类时模板参数是未知的,但是在用模板类实例化对象时需要传入模板类的类型,所以模板类都会被具体的类型所替代;
(2)模板类的继承和一般类的继承规则是一样的,区别是继承父类时,父类中模板参数也会继承下来,子类在继承时需要给父类的模板参数指定具体类型,否则父类中的模板参数就还是未知,这样是会报错;

6、非类型模板参数

6.1、示例代码

#include <iostream>
#include <string>using namespace std;//非类型模板参数类
//T是类型模板,代表一个未知数据类型
//MAX是整数类型但是值未知,需要在定义模板类的对象时指定
template <typename T, int MAX>
class People
{public:char buffer[MAX];T info;People(){};People(T a){info = a;}void print(void){cout << "" << info <<endl;cout << "sizeof(buffer) = " << sizeof(buffer) << endl;}
};//非类型模板参数函数
//T是类型模板,代表一个未知数据类型
//VAL是整数类型但是值未知,需要在使用模板函数时指定
template <typename T, int VAL>
T addValue (T const& x)
{ return x + VAL;
}int main(void)
{People<string, 77> p("hello word!"); p.print();int a = 11;cout << "addValue<int, 22>(a) = " << addValue<int, 22>(a) << endl;return 0;
}

6.2、代码分析

[root#]$ ./app
hello word!
sizeof(buffer) = 77
addValue<int, 22>(a) = 33

(1)非类型模板参数类/函数,顾明思义,模板参数代表的不是数据类型而是某个值;
(2)类型模板参数在示例化时指定数据类型,非类型模板参数在示例化时指定具体的值,思路都是一样的;
(3)非类型模板参数型限制:可以是常整数(包括enum枚举类型)或者指向外部链接对象的指针,但是浮点数和类对象(class-type)不允许作为非类型模板参数:

推荐

我会在C++专栏持续根据更新C++相关的知识点,这里也给大家推荐一款学习C++的神器,我也是在用这一款神器在学习C++。
链接:学习神器跳转
如果你是想入门C++这门语言或者是找C++岗位的工作,都推荐你试试这个网站,里面有针对C++知识点的选择题、编程题,更有C++岗位的面试题,还可以在里面交流行业信息

【C++模板编程入门】模板介绍、模板定义、函数模板、类模板、模板的继承相关推荐

  1. php博客手机版模板下载器,【织梦模板下载】高端响应式游艇租赁类网站模板(自适应手机端) PHP源码带数据...

    模板名称: 响应式游艇租赁类网站织梦模板(自适应手机端)+PC+wap+利于SEO优化 模板介绍: 织梦最新内核开发的模板,该模板属于电缆.电线类企业都可使用, 这款模板使用范围极广,不仅仅局限于一类 ...

  2. Java网络编程入门,包含网络相关概念、InetAddress类、套接字Socket、网络上传和下载文件等

    Java学习-11-韩顺平老师 Java-网络编程入门 目录: 01-网络相关概念 02-InetAddress类 03-套接字Socket 04-网络上传和下载文件 05-UDP网络编程 网络编程相 ...

  3. web大学生个人网站作业模板——上海旅游景点介绍网页代码 家乡旅游网页制作模板 大学生静态HTML网页源码

    家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法,如盒子的嵌套.浮动.margin.border.background等属性的使用,外部大盒子设定居中,内部左中右布局,下方横向浮动排列,大 ...

  4. web大学生个人网站作业模板——上海旅游景点介绍网页代码 家乡旅游网页制作模板 大学生静态HTML网页源码...

    家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法,如盒子的嵌套.浮动.margin.border.background等属性的使用,外部大盒子设定居中,内部左中右布局,下方横向浮动排列,大 ...

  5. django之:网页伪静态 JsonResponse form表单携带文件数据 CBV源码分析 模板语法传值 模板语法之过滤器 标签 自定义标签函数 过滤器、inclusion_tag模板的继承导入

    目录标题 一:网页伪静态 1.定义 2.如何实现 二:视图层 1.视图函数返回值问题 2.视图层返回json格式的数据 3.form表单携带文件数据 4.CBV源码分析 1.CBV和FBV: 2.CB ...

  6. 何先振第1期:Java编程入门计算机介绍

    大家好,我叫何先振,今天给大家介绍下计算机,帮助想学编程的人对计算机有个基本认识. 首先我们来看什么是计算机?计算机是能够按照程序运行控制硬件,自动,高速处理海量数据的现代智能电子设备.计算机的作用就 ...

  7. C语言编程入门——枚举与宏定义

    枚举是编程人员自己定义的一种基本数据类型,这种类型的变量只能取枚举中的值,好处就是能够防止变量的错误赋值.用法:enum 类型名{变量1,变量2,变量3,...} C语言中宏定义是定义在程序头部,作预 ...

  8. [C语言编程入门]带参数宏定义

    问题描述 定义一个带参的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参.输出已交换后的两个值. 解决方案: #include<stdio.h> #define swap( ...

  9. [编程入门]带参数宏定义练习:定义一个带参的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参。输出已交换后的两个值。

    #include<bits/stdc++.h> #define fun(a,b) t=a;a=b;b=t; using namespace std;int main() {int a,b, ...

最新文章

  1. 利用单片机快速实现家庭智能控制平台
  2. 企业想独立完成网站建设也不是不可以
  3. jeecms内容管理系统使用了哪些技术
  4. 【Linux】一步一步学Linux——arp命令(163)
  5. 【深入JavaScript】3.JavaScript继承的实现总结
  6. CSS3中使用translate() 方法实现元素位置的移动
  7. android 弹出弹框2秒消失_基于HTML5 Canvas 实现弹出框
  8. python 入门程序_非Python程序员的Python速成课程-如何快速入门
  9. mybatis plus当月数据查询_Springboot+mybatis(plus)+druid多数据源
  10. python学习之路-day8
  11. mysql怎么让id重新开始自增
  12. 群同态和群同构的区别_顾沛《抽象代数》1.4群的同态与同构习题解答
  13. 怎样屏蔽浏览器关闭按钮及ALT+F4 快捷键
  14. 用matlab演示dsb,DSB-AM的MATLAB仿真
  15. C#图形界面汉诺塔Hanoi
  16. 摩托车挡板防碎膜-安全骑行好伴侣
  17. 大国的崛起:第一集:海洋时代(开篇·葡西)
  18. DIY自制STC单片机开发板
  19. doraemon的python 池
  20. 使用python进行数据分析(二)

热门文章

  1. win7旗舰版 Internet协议版本4的设置方法 --转载
  2. 【西安电子科技大学】考研初试复试资料分享
  3. 内网沟通软件都有哪些?
  4. Android粗浅系统学习(适合入门)
  5. 手把手教echarts中gexf关系图的构造和使用
  6. Matplotlib-几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等,附有代码
  7. 说明书丨ReliaTech艾美捷大鼠羧肽酶-B
  8. Qt发布exe软件及修改exe应用程序图标
  9. LXD共享方案(续)
  10. 2015阿里巴巴实习生招聘笔试题,带答案,欢迎一起来讨论哇!