靖江有帮助做苏宁易购网站的公司吗,wordpress邮箱功能,魅力潍坊网页制作,zhongwen网站模板个人主页~ 模版及STL 一、模版初阶1、泛型编程2、函数模版#xff08;1#xff09;概念#xff08;2#xff09;函数模版格式#xff08;3#xff09;函数模版的原理#xff08;4#xff09;函数模版的实例化①显式实例化②隐式实例化 #xff08;5#xff09;模版参… 个人主页~ 模版及STL 一、模版初阶1、泛型编程2、函数模版1概念2函数模版格式3函数模版的原理4函数模版的实例化①显式实例化②隐式实例化 5模版参数的匹配原则 3、类模版1类模板的定义格式2类模板的实例化以及类函数的使用 二、STL简介 一、模版初阶
1、泛型编程
我们在先前的博文中提到过函数重载交换函数swap但是使用函数重载有几个不好的地方 1、重载的函数仅仅是类型不同代码复用率比较低所有的重载函数中只有数据类型不同其他的都基本相同 只要有新类型出现就需要用户自己增加对应的函数 2、代码可维护性低其中某一函数出错可能会导致所有重载都出错
解决这个问题的方法就是有一个模具只要相同的就直接套用不同的替换就可以了
泛型编程就是编写与类型无关的通用代码是代码复用的一种手段模版是泛型编程的基础
2、函数模版
1概念
函数模版代表了一个函数家族该函数模版与类型无关在使用时被参数化根据实参类型产生函数的特定类型版本
2函数模版格式
templatetypename T1,typename T2,...
type name ()
{}template就是一个函数模版关键字后跟参数放里边 typename是一个类类型参数也可以写成class但不能写成struct它代表name函数可以操作的数据类型。当调用name函数时编译器会根据传递给函数的实参类型来推断T的具体类型 type name{}就是一个函数
具体看这个例子
templatetypename T
void Swap( T left, T right)
{T temp left;left right;right temp;
}3函数模版的原理
模版是编译器用使用方式产生特定具体类型函数的模具它本身并不是函数所以模版就是将本来应该由我们做的重复的事情交给了编译器
在编译器的编译阶段编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用将T确定为某一具体类型然后产生一份专门处理该类型的代码
4函数模版的实例化
用不同类型的参数使用函数模版时称为函数模版的实例化分为显式实例化和隐式实例化
①显式实例化
templatetypename T
T Add(const T left, const T right)
{return left right;
}int main()
{int a 10;double b 20.0;// 显式实例化Addint(a, b);return 0;
}格式函数名数据类型参数
②隐式实例化
templatetypename T
T Add(const T left, const T right)
{return left right;
}
int main()
{int a1 10, a2 20;double d1 10.0, d2 20.0;Add(a1, a2);//意味着T实例化为intAdd(d1, d2);//意味着T实例化为doublereturn 0;
}这是当两个参数类型相同的时候如果两参数类型不同该语句不能通过编译因为在编译期间当编译器看到该实例化时需要推演其实参类型通过实参a1将T推演为int通过实参d1将T推演为double类型但模板参数列表中只有一个T编译器无法确定此处到底该将T确定为int 或者 double类型而报错所以我们要进行手动强制类型转换
注意在模板中编译器一般不会进行类型转换操作
5模版参数的匹配原则
①一个非模版函数可以和一个同名的函数模版同时存在而且该函数模版还可以被实例化为这个非模版函数
int Add(int left, int right)
{return left right;
}templatetypename T
T Add(const T left, const T right)
{return left right;
}int main()
{cout Add(1, 2) endl;//直接与非模版函数相匹配编译器不需要进行特化cout Addint(1, 2) endl;//调用编译器特化的Add版本return 0;
}调试结果 ②对于非模版函数和同名函数模版如果其他条件都相同在调动时会优先调用非模版函数而不会从该模版产生出一个实例但如果模版可以产生一个具有更好的匹配的函数那么将选择模版
int main()
{Add(1, 2);//非模版更匹配会直接选择非模版函数不必再特化Add(1, 2.0);//模版生成的函数比非模版函数更加匹配这样就会选择模版return 0;
}③普通函数可以进行自动类型转换模版函数不允许自动类型转换
3、类模版
1类模板的定义格式
templateclass T1, class T2, ..., class Tn
class name
{// 类内成员定义
}; name是类模板名
接下来我们写一个动态顺序表的模版
templateclass T
class Vector//Vector是类模版名不是类
{
public:Vector(size_t capacity 10): _pData(new T[capacity]), _size(0), _capacity(capacity){}
//模版外定义函数~Vector();void PushBack(const T data);
//模版内定义函数void PopBack(){_size--;}size_t Size(){return _size;}private:T* _pData;size_t _size;size_t _capacity;
};
// 类模板中函数放在类外进行定义时需要加模板参数列表
template class T
VectorT::~Vector()
{if (_pData)delete[] _pData;_size _capacity 0;
}
//每次函数定义都要加模版参数列表
template class T
void VectorT::PushBack(const T data)
{if (_size _capacity){size_t newcapacity _capacity * 2;T* ptr new T[newcapacity];for (int i 0; i _size; i){ptr[i] _pData[i];}delete[] _pData;//用delete[]回收new[]申请的空间_pData ptr;_capacity newcapacity;}_pData[_size] data;_size;
}2类模板的实例化以及类函数的使用
类模板实例化需要在类模板名字后加然后将实例化的类型放在里边类模板不是类实例化后才为类
int main()
{Vectorint s1;s1.PushBack(1);s1.PushBack(2);s1.PushBack(3);s1.PushBack(4);s1.PopBack();cout s1.Size() endl;Vectordouble s2;return 0;
}调试结果
二、STL简介
STL是标准库的组成部分是一个可复用的组件库和包罗数据结构与算法的软件框架
STL有四个版本分别是惠普版本也叫原始版本、P.J.版本VC、RW版本、SGI版本Linux
STL由容器、算法、仿函数、空间配置器、迭代器、配接器六大组件构成
STL的产生是C的一次巨变它使得很多底层的数据结构及算法不用再让程序员来实现大大提高了学习和工作的效率和开发产品的进度
当然STL也有更新慢、不支持线程安全、内部复杂、代码膨胀等问题 今日分享到此结束~