一、模板的作用

建立一个通用函数,其函数返回值类型和形参类型可以不具体确定,用一个虚拟的类型来代表。

template<typename T>

二、示例

1、不使用模板写两个交换变量数值

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;
}int main()
{int a = 10;int b = 20;SwapInt(a, b);cout << a << endl;cout << b << endl;system("pause");return 0;
}

2、使用模板交换两个变量数值

template<typename T>
void Swap(T& a,T&b)
{T temp = a;a = b;b = temp;
}int main()
{int a = 10;int b = 20;Swap(a, b);      //自动推导类型Swap<int>(a, b); //显示指定类型cout << a << endl;cout << b << endl;system("pause");return 0;
}

三、使用模板时的注意事项

1、自动类型推导,必须推导出一致的数据类型T,才能使用

    int a = 10;int b = 20;char c = 'c';Swap(a, b);    //自动推导类型//Swap(a, c);  //报错,自动推导时类型必须相同

2、模板必须要确定出T的数据类型,才可以使用

template<typename T>
void func()
{cout << "111" << endl;
}int main()
{//func();    //错误,模板不能独立使用,必须确定出T的类型func<int>(); //利用显示置定类型的方法,给T一个类型,才可以使用模板system("pause");return 0;
}

四、函数模板案例

案例描述:

①利用函数模板封装一个排序函数,可以对不同数据类型数组进行排序

②排序规则从大到小,排序算法为冒泡排序

③分别利用char数组和int数组进行测试

template<typename T>
void Swap(T &a,T &b)
{T temp = a;a = b;b = temp;
}template<class T>
void Sort(T arr[],int len)
{for (int i = 0; i < len - 1;i++){for (int j = 0; j < len - 1 - i;j++){if(arr[j]>arr[j+1]){Swap(arr[j], arr[j + 1]);}}}
}template<typename T>
void printArray(T arr[],int len)
{for (int i = 0; i < len;i++){cout << arr[i] << endl;}cout << endl;
}void text_char()
{char charArr[] = "qwerasd";int num = sizeof(charArr) / sizeof(char);Sort(charArr, num);printArray(charArr, num);
}void text_int()
{int intArr[] = {7, 4, 1, 8, 5, 0, 2, 9, 6, 3};int num = sizeof(intArr) / sizeof(intArr[0]);Sort(intArr, num);printArray(intArr, num);
}int main()
{//text_char();text_int();system("pause");return 0;
}

五、普通函数与函数模板调用规则

1、如果函数模板和普通模板都可以实现,优先调用普通函数

2、可以通过空模版参数列表来强制调用函数模板

3、函数模板也可以发生重载,此时调用函数模板

4、如果函数模板可以产生更好的匹配,优先调用函数模板

void myPrint(int a,int b)
{cout << "调用普通函数" << endl;
}template<typename T>
void myPrint(T a,T b)
{cout << "调用模板" << endl;
}template<typename T>
void myPrint(T a,T b,T c)
{cout << "调用重载模板" << endl;
}int main()
{int a = 10;int b = 20;//如果函数模板和普通模板都可以实现,优先调用普通函数myPrint(a, b);//可以通过空模版参数列表来强制调用函数模板myPrint<>(a, b);//函数模板也可以发生重载,此时调用函数模板int c = 30;myPrint(a, b, c);//如果函数模板可以产生更好的匹配,优先调用函数模板char c1 = 'a';char c2 = 'b';myPrint(c1, c2);system("pause");return 0;
}

六、模板的局限性

模板的通用性并不是万能的

例如:

template<typename T>
void f(T a,T b)
{a = b;
}

在上述代码中提供的幅值操作,如果传入的a和b是一个数组,就无法实现了。

template<class T>
void f(T a,T b)
{if(a>b){}
}

在上述代码中,如果T的数据类型传入的是Person这样的自定义数据类型,也无法正常运行。

因此,c++提供了模板的重载,可以为这些特定类型提供具体化的模板

示例:

class Person
{
public:Person(string name,int age){this->m_Name = name;this->m_Age = age;}public:string m_Name;int m_Age;
};//普通函数模板
template<class T>
bool myCompare(T& a,T&b)
{if(a==b){return true;}else{return false;}
}//具体化,显示具体化的原型和定意义以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<> bool myCompare(Person &p1,Person &p2)
{if(p1.m_Name==p2.m_Name&&p1.m_Age==p2.m_Age){return true;}else{return false;}
}void text01()
{int a = 10;int b = 20;bool ret = myCompare(a, b);if(ret){cout << "a=b" << endl;}else{cout << "a!=b"<<endl;}
}void text02()
{Person p1("Tom", 10);Person p2("Tom", 10);bool ret = myCompare(p1, p2);if(ret){cout << "p1==p2" << endl;}else{cout << "p1!=p2" << endl;}
}int main()
{//text01();text02();system("pause");return 0;
}

七、类模板

作用:建立一个通用的类,类中成员的数据类型可以不具体制定,用一个虚拟的类型来代表。

template <class NameType,class AgeType>
class Person
{
public:Person(NameType name,AgeType age){this->name = name;this->age = age;}void showPerson(){cout << "name:" << this->name << " age:" << this->age << endl;}public:NameType name;AgeType age;
};void text01()
{Person<string, int> P1("猴子", 99);Person<int, float> P2(12, 1.11);P1.showPerson();P2.showPerson();
}

八、类模板与函数模板的区别

类模板没有自动类型推导的使用方式,且类模板在模板参数列表中可以用默认参数

void text01()
{//Person p("猴子", 1000);  //类模板使用的时候,不可以用自动类型推导Person<string, int> p("孙悟空", 1000);  //必须使用指定的类型方式p.showPerson();
}void text02()
{Person<string> p("猪八戒", 99);  //类模板中的模板参数列表,可以指定默认参数p.showPerson();
}

九、类模板中成员函数创建时机

普通类中的成员函数一开始就可以创建

类模板中的成员函数在调用时才创建

十、类模板对象做函数参数

1、指定传入的类型:直接显示对象的数据类型

void printPerson1(Person<string,int> &p)
{p.showPerson();
}void text01()
{Person<string, int> p("孙悟空", 100);printPerson1(p);
}

2、参数模板化:将对象中的参数变为模板进行传递

template <class T1,class T2>
void printPerson2(Person<T1, T2>&p)
{p.showPerson();
}void text02()
{Person <string, int> p("猪八戒", 200);printPerson2(p);
}

3、整个类模板化:将这个对象类型模板化进行传递

template<class T>
void printPerson3(T &p)
{p.showPerson();
}void text03()
{Person<string, int> p("唐僧", 300);printPerson3(p);
}

十一、类模板与继承

1、当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型

template<class T>
class Base
{T m;
};//class Son:public Base     //错误,没有指出父类中T的类型
class Son:public Base<int>  //必须指定一个类型
{
};void text01()
{Son s;
}

2、如果不指定,编译器无法给子类分配内存

3、如果想灵活指定出父类中T的内存,子类也需变为类模板

template<class T1,class T2>
class Son2:public Base<T2>
{
public:Son2(){cout << typeid(T1).name() << endl;cout << typeid(T2).name() << endl;}
};void text02()
{Son2<int, char> child;
}

十二、类模板成员函数类外实现

//类模板中成员函数类外实现
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;
}void text01()
{Person<string, int> p("abs", 10);p.showPerson();
}

十三、类模板与友元

全局函数类内实现:直接在类内声明友元即可

全局函数类外实现:需要提前让编译器知道全局函数的存在

//2、全局函数配合友元 类外实现 先做函数模板声明,下方在做函数模板定义,在做友元
template <class T1, class T2>class Person;template<class T1,class T2>
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 text01()
{Person <string,int>p("Tom",20);printPerson(p);
}//2、全局函数在类外实现
void text02()
{Person <string,int>p("Jerry",20);printPerson2(p);
}

cpp学习笔记:模板相关推荐

  1. C++学习笔记:模板

    C++学习笔记:模板 1.函数模板 2.类模板 2.1类模板注意事项 2.2类模板中函数的创建时机 2.3类模板对象作函数参数时 2.4类模板与继承 2.5类模板分文件编写 2.6类模板友元 2.6. ...

  2. 设计模式学习笔记——模板(Template)模式

    设计模式学习笔记--模板(Template)模式 @(设计模式)[设计模式, 模板模式, template, 模板方法] 设计模式学习笔记模板Template模式 基本介绍 模板案例 类图 实现代码 ...

  3. 图论01.最短路专题_学习笔记+模板

    图论01.最短路专题_学习笔记+模板 一.定义与性质 ● 需要的前导知识点 路径 最短路 有向图中的最短路.无向图中的最短路 单源最短路.每对结点之间的最短路 ● 最短路的性质 对于边权为正的图,任意 ...

  4. image是否有disabled属性_Vue学习笔记 模板语法、计算属性

    点击上方"蓝字"关注我们吧! vue学习笔记 官网:https://cn.vuejs.org/v2/guide/ 1.vue体验 demo示例: image.png 示例代码: & ...

  5. C++模板学习笔记——模板实参

    对于函数模板,编译器通过隐式推断模板实参.其中,从函数实参来确定模板实参的过程被称为模板实参推断.在模板实参推断过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定 ...

  6. C++学习笔记—模板与STL

    C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 例如生活中的模板 一寸照片模板 PPT ...

  7. [C++]学习笔记——模板

    针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用. 1.模板 1.1模板的概念 模板就是建立通用的模具,大大提高复用性 日常生活例子帮助理解:一寸照片模板.PPT模板 1.2函数模板语 ...

  8. 菜鸟教程Cpp学习笔记

    一.面向对象开发的特征 面向对象开发的四大特性: 封装 抽象 继承 多态 二.C++ 中的类型限定符 限定符 含义 const const 类型的对象在程序执行期间不能被修改改变. volatile ...

  9. C++学习笔记-------模板(template)

    文章目录 1.函数模板 2.类模板 2.1类模板的基本使用 2.2类模板中的友元 3.模板默认参数 3.1模板函数的默认参数 3.2类模板默认参数 4.成员模板 4.1普通类的成员模板 4.2模板类的 ...

最新文章

  1. C语言----项目构建Make,Automake,CMake
  2. python运行速度和电脑配置有关系吗-学python最电脑配置有要求么
  3. linux创建更改目录,如何使用Linux中的单个命令创建新目录并更改它 | MOS86
  4. DataSource--DBCP--C3P0--DBUtils
  5. 用十条命令在一分钟内检查Linux服务器性能
  6. controller如何保证当前只有一个线程执行_聊聊Spring线程安全,读完之后,大部分程序员收藏了......
  7. 最实用的APP界面设计知识,有温度的APP设计(转)
  8. 传递json_开发技巧分享—JSON 数据格式及函数讲解
  9. 2018年7月第一周网站建站笔记
  10. Improving Opencv 4: The Core Functionality :Operations with images
  11. PAIP.提升安全性---更好的签名HASH算法
  12. 文本密度 php,基于最大文本密度的网页正文抽取方法
  13. Android App 启动时显示正在加载图片(源码)
  14. gms认证流程_Android P(9.0)GMS认证新要求
  15. 基于国密算法SM2非证书标识公钥密码技术(IPK)
  16. 新版个人所得税计算python_最新个税计算 / 个税计算器 小程序 wepy 开发
  17. 跟着团子学SAP PS:项目计划成本与项目预算设计思路
  18. Pyhon中利用GM(1,1)和ARIMA模型对卫星DCB值进行预测
  19. 节假日配置、工作日配置
  20. 骑士周游 探索访问

热门文章

  1. PMP备考大全:经典题库(敏捷管理第5期)
  2. 工作组与域环境下NTLM协议数据包分析
  3. MindMaster-------ERP系统上线计划
  4. 半路出家当程序员容易吗?怎样才能拿高薪?
  5. Allure环境部署与生成+Allure内容增强
  6. java 时间戳 周几_Java:Unix时间戳记中的日期
  7. 构建中国云生态 | 华云数据与杉岩数据完成产品兼容互认证 携手满足更多用户海量数据的管理需求
  8. 基于JSP的房地产销售网
  9. 织梦小说,搜索功能,搜索结果是栏目而不是文章
  10. 小船翻了,路还得继续