编程细节:
模板类的编写和非模板类编写上有个很大区别,类定义和声明不可以分开写,成员函数的定义要写在头文件中!因为这个问题坑了好久!!!
|--------------------------------------------------------------------------------------------------------
原理阐述:
为什么需要template理念?
这些高级的语法都是为了使得编程更简单!减少代码冗余!
之前的文章中,讲过函数模板,函数实现的内容相同,只有数据类型不同!针对这样的情况,我们将数据抽离出来以类型参数代替。面向对象的理念是将具有继承关系的类的方法抽离出来,视情况实现一份或是多份。总之,目标是能不自己写代码就不写,利用编译器为我们提供的机制,易读更安全!
template 参数可分为类型参数和非类型参数!分别来说说吧!
类型参数:
将类设计中所依赖的数据类型抽离出作为类型参数!实例化时将根据具体的类型生成不同的特殊类。数据类型可以是内建类型、自定义类型!其中一个比较特别的自定义类型,函数对象类型!不同的参数类型,也能决定函数实现的内容了!
当我们的参数类型是函数对象时,在模板类的内部可以使用不同的函数实现来完成我们的类设计!这已经不是最初哪个简单地与数据类型无法的模板类设计初衷了,而是使得模板类可实现的内容更广泛!
先来份简单的抽离数据类型:
其实上面的编程是存在缺陷的,我们并不知道实际的数据类型是什么,类内有实现比较运算符吗?不清楚啊!这说明我们的类设计不安全,如何解决呢?在使用该函数对象时,必须要指出比较方式!比较方式由用户实现(函数对象类型),为此,在实现比较元素的类的类型参数多加一个参数(实例化为函数对象)进行比较方式的确定。下图中有一个编程问题,调用模板函数对象的时候一定要初始化后再传递参数!原写为**Comp(val,_val)**在visual studio 2015 编译产生错误!应该为Comp()(val,_val)!!!先创建对象才能调用方法!
#include<functional>
#include<string>
//默认参数又是一个模板类,类型与这个模板类的参数类型有关
template<class EleType,class OperatorType=std::less<EleType>>
class Compare {
private:
EleType _val;
public:
Compare(const EleType &v):_val(v){}
bool operator()(const EleType & c) {
//OperatorType a;
//return a(_val, c);
return OperatorType()(_val, c);
}
void set_value(EleType & c) {
_val = c;
}
const EleType& get_value() const {
return _val;
}
};
//具体类,就是用于比较字符串的
class OperatorString {
public:
bool operator()(const std::string & a, const std::string & b) {
return a.size() < b.size();
}
};
#include<vector>
#include<algorithm>
#include<iostream>
#include"compare.h"
int main()
{
//ompare<int> a(10);
std::vector<int > b = { 4,3,56,7,2 ,3};
auto it1 = find_if(b.begin(), b.end(), Compare<int>(3));
std::cout<<*it1<<std::endl;
std::vector < std::string > a = { "kdfj","lxy","lxy" };
//sort(a.begin(), a.end(),Compare);
auto it = a.begin();
//auto temp = a.begin();
while (( it= find_if(it, a.end(), Compare<std::string, OperatorString>("a"))) != a.end())
std::cout << *it++ << " ";
std::cout << std::endl;
std::cin.get();
return 0;
}
另一个例子,体现了参数类型是用户自定义类型!而在模板类的设计中可以直接使用类型参数的方法,在实例化为不同的类型后,这么一个模板类可表现出多个方法实现内容不同的类!感觉脑洞好大!!!好灵活!!!
模板类的设计同普通类相似,支持继承(多态)、友元等概念。
tem