一、模板的概述
c++面向对象编程思想:封装、继承、多态
c++泛型编程思想:模板
模板的分类:函数模板、类模板
函数模板(类模板):将功能相同,类型不同的函数(类)的类型抽象成虚拟的类型(函数类型和形参类型不具体指定)。不必定义多个函数,当调用函数(类实例化对 象)的时候,编译器自动将虚拟的类型 具体化。
二、函数模板
1、关键字template说明
函数模板 会编译两次:
第一次:对函数模板 代码本身编译
第二次:函数调用处 将T的类型具体化替换后的代码进行编译
函数模板目标:模板是为了实现泛型,可以减轻编程的工作量,增强函数的重用性。
2、注意点
(1)函数模板 和 普通函数 都识别,同名时优先选择 普通函数。
(2)函数模板 和 普通同名函数 都存在时,强制使用函数模板:
(3)有函数模板 自动类型推导时,一般不会对其函数参数 进行 自动类型转换,普通函数会自动类型转换。
(4)函数模板可以重载
(5)模板的局限性:当函数模板 推导出 T为数组、结构体或其他自定义类型数据 可能导致运算符 不识别。
解决办法1:运算符重载
解决办法2:具体化函数模板
三、类模板
1、定义
有两个或多个类,其功能是相同的,仅仅是数据类型不同。类模板用于实现类所需数据的类型参数化。
类模板 将类中类型 抽象成虚拟类型:
类模板 的成员函数 在类外实现:
2、函数模板作为类模板的友元
3、普通函数作为类模板的友元
四、类模板的继承
1、类模板 派生出 普通类
2、类模板 派生出 类模板
3、类模板头文件 和源文件不可分离
类模板存储在.hpp(头文件和源文件结合)中
data.hpp
#ifndef DATA_H
#define DATA_H
#include<iostream>
using namespace std;
template<class T1,class T2>
class Data
{
private:T1 a;T2 b;
public:Data();Data(T1 a,T2 b);void showData(void);
};
template<class T1, class T2>
Data<T1, T2>::Data()
{cout<<"无参构造"<<endl;
}
template<class T1, class T2>
Data<T1,T2>::Data(T1 a, T2 b)
{this->a=a;this->b=b;
}
template<class T1, class T2>
void Data<T1,T2>::showData(void)
{cout<<a<<" "<<b<<endl;
}#endif // DATA_H
主测试程序main.cpp
#include <iostream>
#include"data.hpp"using namespace std;int main(int argc, char *argv[]){Data<int,char> ob(10,'A');ob.showData();return 0;}
五、设计数组类模板
六、C++中类型转换
1、上行、下行转换
2、static_cast静态类型转换
类型转换(cast)是将一种数据类型转换成另一种数据类型。
static_cast静态类型转换用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
基本类型:支持
int num = static_cast<int>(3.14);//3.14转成int类型ok
定义三个无数据类如下
class Base{};class Son:public Base{};class Other{};
上行转换:支持 安全
Base *p = static_cast(new Son);
下行转换:支持 (不安全)
Son *p2 = static_cast(new Base);
不相关类型转换:不支持
Base *p3 = static_cast(new Other);//err报错
3、dynamic_cast静态类型转换
dynamic_cast主要用于类层次间的上行转换和下行转换。在类层次间进行上行转换时,dynamic_cast 和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比.static_cast更安全。
基本类型:不支持
int num = static_cast<int>(3.14);//err
上行转换:支持
Base *p = static_cast(new Son);
下行转换:不支持 不安全
Son *p2 = static_cast(new Base); //err
不相关类型转换:不支持
Base *p3 = static_cast(new Other);//err
4、const_cast常量转换
该运算符用来修改类型的const属性。
(1)常量之间可直接 const属性转换
const int num1=10;
int data1=num1;int num2=10;
const int data2=num2;
(1)将const修饰的指针或引用 转换成 非const
const int *p1;
int *p2 = const_cast<int *>(p1);const int &ob = 10;
int &ob1 = const_cast<int &>(ob);
(2)将非const修饰的指针或引用 转换成 const
int *p3;
const *p4 = const_cast<int *>(p3);//或const *p4 = p3;int data = 10;
const int &ob2 = const_cast<const int &>(data);//或const int &ob2 =data;
5、重新解释转换(reinterpret_cast) (最不安全)
除基本类型不可强转,其他均可强制类型转换。