最近对c++产生浓厚的兴趣,于是开始看c++的泛型编程。
我觉得泛型编程的作用就在于增加代码的复用率,这一点和多态与继承相似。
首先看一个问题,我们要在一个vector<int>中寻找某个值的地址。
这个函数可以满足这样需求,那现在如果要求在一个vector<string>,vector<double>中寻找某个值了。当然你可以用函数的重载来实现find(),但是这显然不是最好的实现了。因为我们有模板来更加方便的实现。
template<typename Type>
Type* _find(vector<Type> &vec,const Type &val)
{
for(int i=0;i<vec.size();i++)
if(vec[i]==val)
return &vec[i];
return 0;
}
Type* _find(vector<Type> &vec,const Type &val)
{
for(int i=0;i<vec.size();i++)
if(vec[i]==val)
return &vec[i];
return 0;
}
好了 现在我们可以尽情的对vector对象应用find()。但是如果应用的对象是一个array了。难道又要使用多态。当然我们还可以讲模板进行到底。我们知道vector和array都是连续分布在内存上的,对于每一个对象我们都可以指针来表示。于是我们可以使用指针来完成find()
template<typename type>
type* _find(type *_sta,const type *_end,const type &val)
{
for(;_sta!=_end;_sta++)
if(*_sta==val)
return _sta;
return 0;
}
type* _find(type *_sta,const type *_end,const type &val)
{
for(;_sta!=_end;_sta++)
if(*_sta==val)
return _sta;
return 0;
}
其中_sta表示起始地址,_end表示结束地址。指针指向每个值,_sta++表示下一个元素。但是这样做同样也有缺陷。我们发现指针的自增只能指向内存的下一个位置,当面对的对象在内存上的分布不是连续内存的时候,这个函数是不能完成任务的时候。这个时候,c++中的iterator出场了。我们可以理解为,iterator为高级的指针,他可以完成对象地址的自增等操作。
template<typename iteratorType,typename valueType>
iteratorType _find(iteratorType first,iteratorType last,const valueType val)
{
for(;first!=last;first++)
if(*first==val)
return first;
return last;
}
iteratorType _find(iteratorType first,iteratorType last,const valueType val)
{
for(;first!=last;first++)
if(*first==val)
return first;
return last;
}
其中first,last都是传入的iterator类型。标示出查找的区间。
调用这个函数:
int main()
{
vector<int> a;
a.push_back(1);
a.push_back(2);
int b[]={1,2,3};
int *b=_find(&b[0],&b[2],2);
vector<int>::iterator k=_find(a.begin(),a.end(),3);
}
{
vector<int> a;
a.push_back(1);
a.push_back(2);
int b[]={1,2,3};
int *b=_find(&b[0],&b[2],2);
vector<int>::iterator k=_find(a.begin(),a.end(),3);
}
至此,成功的完成了使用对象和find()函数的分离。
至于如何定义的iterator,下次继续学习。
浙公网安备 33010602011771号