stlvector源码(stl 源码)
本文目录一览:
- 1、如何看待或理解 对于STL:vector的如下见解
- 2、求STL中vector中insert函数的源代码 最好加上注释
- 3、stl vector 内部是用什么实现
- 4、stl源码剖析 为什么要使用仿函数
- 5、关于STL vector的实现 答对加100
如何看待或理解 对于STL:vector的如下见解
《STL系列》之vector原理及实现
最近忙得蛋疼,但还是想写点属于自己的东西。也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现。实现目标就是:1能和STL兼容;2最大化的实现STL中的接口并保持一致。即将STL中的集合换成我写的也能用。这篇博客介绍的是vector的原理及实现。
先把vector的大致实现说一下,后面会给出完整的源码。
新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。
void insert(const_iterator iter,const T t )
{
int index=iter-begin();
if (indexsize_)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
memmove(buf+index+1,buf+index,(size_-index)*sizeof(T));
buf[index]=t;
size_++;
}
}
删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。
删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。
iterator erase(const_iterator iter)
{
int index=iter-begin();
if (indexsize_ size_0)
{
memmove(buf+index ,buf+index+1,(size_-index)*sizeof(T));
buf[--size_]=T();
}
return iterator(iter);
}
求STL中vector中insert函数的源代码 最好加上注释
还是直接看vector standard header比较好,直接贴出来不好阅读。
源代码VC和VS的目录里有,比如VC8路径:C:\Program Files\Microsoft Visual Studio 8\VC\include里的vector。
//insert
_Myt __CLR_OR_THIS_CALL insert(size_type _Off,
const _Myt _Right, size_type _Roff, size_type _Count)
{ // insert _Right [_Roff, _Roff + _Count) at _Off
if (_Mysize _Off || _Right.size() _Roff)
_String_base::_Xran(); // _Off or _Roff off end
size_type _Num = _Right.size() - _Roff;
if (_Num _Count)
_Count = _Num; // trim _Count to size
if (npos - _Mysize = _Count)
_String_base::_Xlen(); // result too long
if (0 _Count _Grow(_Num = _Mysize + _Count))
{ // make room and insert new stuff
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off, _Mysize - _Off); // empty out hole
if (this == _Right)
_Traits_helper::move_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Myptr() + (_Off _Roff ? _Roff + _Count : _Roff),
_Count); // substring
else
_Traits_helper::copy_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Right._Myptr() + _Roff, _Count); // fill hole
_Eos(_Num);
}
return (*this);
}
_Myt __CLR_OR_THIS_CALL insert(size_type _Off,
const _Elem *_Ptr, size_type _Count)
{ // insert [_Ptr, _Ptr + _Count) at _Off
if (_Inside(_Ptr))
return (insert(_Off, *this,
_Ptr - _Myptr(), _Count)); // substring
if (_Mysize _Off)
_String_base::_Xran(); // _Off off end
if (npos - _Mysize = _Count)
_String_base::_Xlen(); // result too long
size_type _Num;
if (0 _Count _Grow(_Num = _Mysize + _Count))
{ // make room and insert new stuff
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off, _Mysize - _Off); // empty out hole
_Traits_helper::copy_s_Traits(_Myptr() + _Off, _Myres - _Off, _Ptr, _Count); // fill hole
_Eos(_Num);
}
return (*this);
}
_Myt __CLR_OR_THIS_CALL insert(size_type _Off, const _Elem *_Ptr)
{ // insert [_Ptr, null) at _Off
return (insert(_Off, _Ptr, _Traits::length(_Ptr)));
}
_Myt __CLR_OR_THIS_CALL insert(size_type _Off,
size_type _Count, _Elem _Ch)
{ // insert _Count * _Ch at _Off
if (_Mysize _Off)
_String_base::_Xran(); // _Off off end
if (npos - _Mysize = _Count)
_String_base::_Xlen(); // result too long
size_type _Num;
if (0 _Count _Grow(_Num = _Mysize + _Count))
{ // make room and insert new stuff
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off, _Mysize - _Off); // empty out hole
_Chassign(_Off, _Count, _Ch); // fill hole
_Eos(_Num);
}
return (*this);
}
iterator __CLR_OR_THIS_CALL insert(iterator _Where)
{ // insert null at _Where
return (insert(_Where, _Elem()));
}
iterator __CLR_OR_THIS_CALL insert(iterator _Where, _Elem _Ch)
{ // insert _Ch at _Where
size_type _Off = _Pdif(_Where, begin());
insert(_Off, 1, _Ch);
return (begin() + _Off);
}
void __CLR_OR_THIS_CALL insert(iterator _Where, size_type _Count, _Elem _Ch)
{ // insert _Count * _Elem at _Where
size_type _Off = _Pdif(_Where, begin());
insert(_Off, _Count, _Ch);
}
templateclass _It
void __CLR_OR_THIS_CALL insert(iterator _Where, _It _First, _It _Last)
{ // insert [_First, _Last) at _Where
_Insert(_Where, _First, _Last, _Iter_cat(_First));
}
templateclass _It
void __CLR_OR_THIS_CALL _Insert(iterator _Where, _It _Count, _It _Ch,
_Int_iterator_tag)
{ // insert _Count * _Ch at _Where
insert(_Where, (size_type)_Count, (_Elem)_Ch);
}
templateclass _It
void __CLR_OR_THIS_CALL _Insert(iterator _Where, _It _First, _It _Last,
input_iterator_tag)
{ // insert [_First, _Last) at _Where, input iterators
replace(_Where, _Where, _First, _Last);
}
void __CLR_OR_THIS_CALL insert(iterator _Where, const_pointer _First, const_pointer _Last)
{ // insert [_First, _Last) at _Where, const pointers
replace(_Where, _Where, _First, _Last);
}
void __CLR_OR_THIS_CALL insert(iterator _Where, const_iterator _First, const_iterator _Last)
{ // insert [_First, _Last) at _Where, const_iterators
replace(_Where, _Where, _First, _Last);
}
//replace
_Myt __CLR_OR_THIS_CALL replace(size_type _Off, size_type _N0, const _Myt _Right)
{ // replace [_Off, _Off + _N0) with _Right
return (replace(_Off, _N0, _Right, 0, npos));
}
_Myt __CLR_OR_THIS_CALL replace(size_type _Off,
size_type _N0, const _Myt _Right, size_type _Roff, size_type _Count)
{ // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
if (_Mysize _Off || _Right.size() _Roff)
_String_base::_Xran(); // _Off or _Roff off end
if (_Mysize - _Off _N0)
_N0 = _Mysize - _Off; // trim _N0 to size
size_type _Num = _Right.size() - _Roff;
if (_Num _Count)
_Count = _Num; // trim _Count to size
if (npos - _Count = _Mysize - _N0)
_String_base::_Xlen(); // result too long
size_type _Nm = _Mysize - _N0 - _Off; // length of preserved tail
size_type _Newsize = _Mysize + _Count - _N0;
if (_Mysize _Newsize)
_Grow(_Newsize);
if (this != _Right)
{ // no overlap, just move down and copy in new stuff
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // empty hole
_Traits_helper::copy_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Right._Myptr() + _Roff, _Count); // fill hole
}
else if (_Count = _N0)
{ // hole doesn't get larger, just copy in substring
_Traits_helper::move_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _Count); // fill hole
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
}
else if (_Roff = _Off)
{ // hole gets larger, substring begins before hole
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _Count); // fill hole
}
else if (_Off + _N0 = _Roff)
{ // hole gets larger, substring begins after hole
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Myptr() + (_Roff + _Count - _N0), _Count); // fill hole
}
else
{ // hole gets larger, substring begins in hole
_Traits_helper::move_s_Traits(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _N0); // fill old hole
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s_Traits(_Myptr() + _Off + _N0, _Myres - _Off - _N0, _Myptr() + _Roff + _Count,
_Count - _N0); // fill rest of new hole
}
_Eos(_Newsize);
return (*this);
}
_Myt __CLR_OR_THIS_CALL replace(size_type _Off,
size_type _N0, const _Elem *_Ptr, size_type _Count)
{ // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
if (_Inside(_Ptr))
return (replace(_Off, _N0, *this,
_Ptr - _Myptr(), _Count)); // substring, replace carefully
if (_Mysize _Off)
_String_base::_Xran(); // _Off off end
if (_Mysize - _Off _N0)
_N0 = _Mysize - _Off; // trim _N0 to size
if (npos - _Count = _Mysize - _N0)
_String_base::_Xlen(); // result too long
size_type _Nm = _Mysize - _N0 - _Off;
if (_Count _N0)
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up
size_type _Num;
if ((0 _Count || 0 _N0) _Grow(_Num = _Mysize + _Count - _N0))
{ // make room and rearrange
if (_N0 _Count)
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::copy_s_Traits(_Myptr() + _Off, _Myres - _Off, _Ptr, _Count); // fill hole
_Eos(_Num);
}
return (*this);
}
_Myt __CLR_OR_THIS_CALL replace(size_type _Off, size_type _N0, const _Elem *_Ptr)
{ // replace [_Off, _Off + _N0) with [_Ptr, null)
return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
}
_Myt __CLR_OR_THIS_CALL replace(size_type _Off,
size_type _N0, size_type _Count, _Elem _Ch)
{ // replace [_Off, _Off + _N0) with _Count * _Ch
if (_Mysize _Off)
_String_base::_Xran(); // _Off off end
if (_Mysize - _Off _N0)
_N0 = _Mysize - _Off; // trim _N0 to size
if (npos - _Count = _Mysize - _N0)
_String_base::_Xlen(); // result too long
size_type _Nm = _Mysize - _N0 - _Off;
if (_Count _N0)
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up
size_type _Num;
if ((0 _Count || 0 _N0) _Grow(_Num = _Mysize + _Count - _N0))
{ // make room and rearrange
if (_N0 _Count)
_Traits_helper::move_s_Traits(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Chassign(_Off, _Count, _Ch); // fill hole
_Eos(_Num);
}
return (*this);
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last, const _Myt _Right)
{ // replace [_First, _Last) with _Right
return (replace(
_Pdif(_First, begin()), _Pdif(_Last, _First), _Right));
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last, const _Elem *_Ptr,
size_type _Count)
{ // replace [_First, _Last) with [_Ptr, _Ptr + _Count)
return (replace(
_Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count));
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last, const _Elem *_Ptr)
{ // replace [_First, _Last) with [_Ptr, null)
return (replace(
_Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr));
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last,
size_type _Count, _Elem _Ch)
{ // replace [_First, _Last) with _Count * _Ch
return (replace(
_Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch));
}
templateclass _It
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last,
_It _First2, _It _Last2)
{ // replace [_First, _Last) with [_First2, _Last2)
return (_Replace(_First, _Last,
_First2, _Last2, _Iter_cat(_First2)));
}
templateclass _It
_Myt __CLR_OR_THIS_CALL _Replace(iterator _First, iterator _Last,
_It _Count, _It _Ch, _Int_iterator_tag)
{ // replace [_First, _Last) with _Count * _Ch
return (replace(_First, _Last, (size_type)_Count, (_Elem)_Ch));
}
templateclass _It
_Myt __CLR_OR_THIS_CALL _Replace(iterator _First, iterator _Last,
_It _First2, _It _Last2, input_iterator_tag)
{ // replace [_First, _Last) with [_First2, _Last2), input iterators
_Myt _Right(_First2, _Last2);
replace(_First, _Last, _Right);
return (*this);
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last,
const_pointer _First2, const_pointer _Last2)
{ // replace [_First, _Last) with [_First2, _Last2), const pointers
if (_First2 == _Last2)
erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
else
replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
*_First2, _Last2 - _First2);
return (*this);
}
_Myt __CLR_OR_THIS_CALL replace(iterator _First, iterator _Last,
const_iterator _First2, const_iterator _Last2)
{ // replace [_First, _Last) with [_First2, _Last2), const_iterators
if (_First2 == _Last2)
erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
else
replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
*_First2, _Last2 - _First2);
return (*this);
}
stl vector 内部是用什么实现
《STL系列》之vector原理及实现
最近忙得蛋疼,但还是想写点属于自己的东西。也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现。实现目标就是:1能和STL兼容;2最大化的实现STL中的接口并保持一致。即将STL中的集合换成我写的也能用。这篇博客介绍的是vector的原理及实现。
先把vector的大致实现说一下,后面会给出完整的源码。
新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。
void insert(const_iterator iter,const T t )
{
int index=iter-begin();
if (indexsize_)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
memmove(buf+index+1,buf+index,(size_-index)*sizeof(T));
buf[index]=t;
size_++;
}
}
删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。
删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。
iterator erase(const_iterator iter)
{
int index=iter-begin();
if (indexsize_ size_0)
{
memmove(buf+index ,buf+index+1,(size_-index)*sizeof(T));
buf[--size_]=T();
}
return iterator(iter);
}
迭代器iteraotr是STL的一个重要组成部分,通过iterator可以很方便的存储集合中的元素.STL为每个集合都写了一个迭代器, 迭代器其实是对一个指针的包装,实现一些常用的方法,如++,--,!=,==,*,-等, 通过这些方法可以找到当前元素或是别的元素. vector是STL集合中比较特殊的一个,因为vector中的每个元素都是连续的,所以在自己实现vector的时候可以用指针代替,如typedef T* iterator;typedef const T* const_iterator,如果STL中的函数能方便的操作自己写的集合,实现的迭代器最好继承std::iteratorstd::forward_iterator_tag,T。我实现vector的迭代器大概是这个样子:
templatetypename T
class viterator:public std::iteratorstd::forward_iterator_tag,T{}
后面会给出完整的代码,std::iteratorstd::forward_iterator_tag,T的源码如下:
templateclass _Category,
class _Ty,
class _Diff = ptrdiff_t,
class _Pointer = _Ty *,
class _Reference = _Ty
struct iterator
{ // base type for all iterator classes
typedef _Category iterator_category;
typedef _Ty value_type;
typedef _Diff difference_type;
typedef _Diff distance_type; // retained
typedef _Pointer pointer;
typedef _Reference reference;
};
Iterator其中没有任何成员,只是定义了一组类型,所以继承它并不会让你的struct变大,这组类型是STL的内部契约,STL中的函数假设每个迭代器都定义了这些类型,所以只要你的迭代器定义了这些类型,就可以和STL函数集合一起使用。
我的vector实现源码如下:
View Code
实例代码级运行结果如下:
struct Point
{
Point(int x_=0,int y_=0):x(x_),y(y_){}
int x,y;
};
bool operator(const Point p1,const Point p2)
{
if(p1.xp2.x)
{
return true;
}else if(p1.xp2.x)
{
return false;
}
return p1.yp2.y;
}
void cvectorTest()
{
cvectorPoint vect;
for (int i=0;i10;i++)
{
Point p(i,i);
vect.push_back(p);
}
cvectorPoint::iterator iter=vect.begin();
while (iter!=vect.end())
{
cout "[" iter-x " " iter-y "], ";
++iter;
}
iter=vect.begin()+5;
vect.insert(iter,Point(55,55));
iter=vect.end()-3;
vect.insert(iter,Point(77,77));
coutendlendl"插入两个元素后:"endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout "[" iter-x " " iter-y "], ";
++iter;
}
std::sort(vect.begin(),vect.end());
coutendlendl"排序后:"endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout "[" iter-x " " iter-y "], ";
++iter;
}
vect.erase(vect.begin()+10);
vect.erase(vect.begin()+10);
coutendlendl"删除之前新增的两个元素"endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout "[" iter-x " " iter-y "], ";
++iter;
}
vect.clear();
coutendlendl"执行clear之后"endl;
cout"size="vect.size()",capacity="vect.capacity();
cvectorPoint vect1;
for (int i=10;i20;i++)
{
Point p(i,i);
vect1.push_back(p);
}
coutendlendl"从别的cvector复制数据:"endl;
cvectorPoint vect2(vect1.begin(),vect1.end());
vect2.pop_back();
vect2.pop_back();
for(int i=0;ivect2.size();i++)
{
cout"["vect2[i].x","vect2[i].y"], ";
}
coutendl;
}
之后还会有list,set,map等的实现,敬请期待......
stl源码剖析 为什么要使用仿函数
STL(standard template libary),标准模板库。
这是C++标准的一部分。关于这个库有不少历史可以说,侯捷的《STL源码剖析》讲了不少。STL有好几种不同的实现,微软也有自己的实现。
关于使用,比如你用了下面的语句:
#include vector
就是使用了标准模板库里的 vector.
然后你这样声明向量:
vectorint a; //向量a包含的元素是int型的
vectordouble b; //向量b包含的元素是double型的
你可以查找对应的头文件,它们都是以源码形式出现的,不过里面的符号定义的让人眼花缭乱,还是找书看比较好。
标准模板库包含了数据结构和算法等方面的内容,比较复杂,学习之前要有十足下信心。
关于STL vector的实现 答对加100
今天看了下源码,确实是通过判断是否是int类型进行不同操作的,具体如下:
首先是这个函数:
template class _InputIterator
vector(_InputIterator __first, _InputIterator __last,
const allocator_type __a = allocator_type()) : _Base(__a) {
typedef typename _Is_integer_InputIterator::_Integral _Integral;
_M_initialize_aux(__first, __last, _Integral());
}
定义了一个类型:
typedef typename _Is_integer_InputIterator::_Integral _Integral;
这个类型会根据_InputIterator的不同而进行不一样的类模板显示具体化,比如说,如果是int类型的话,
__STL_TEMPLATE_NULL struct _Is_integerint {
typedef __true_type _Integral;
};
会将__true_type定义为_Integral,其他非数值情况,会用默认的模板实例化:
template class _Tp struct _Is_integer {
typedef __false_type _Integral;
};
会将__false_type定义为_Integral
然后调用:
_M_initialize_aux(__first, __last, _Integral());
_M_initialize_aux这个函数有重载,会根据_Integral()是__false_type还是__true_type调用不同的重载函数,
两个重载如下:
template class _Integer
void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
_M_start = _M_allocate(__n);
_M_end_of_storage = _M_start + __n;
_M_finish = uninitialized_fill_n(_M_start, __n, __value);
}
template class _InputIterator
void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
__false_type) {
_M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
}
之后的就简单了,就是根据是否是int做出不同的操作就是了
======================================================================
我看的是vc的vector文件,有点不太一样,呵呵
是我想当然了,确实是用模板类的,不过写的挺麻烦的、
你可以到网上搜一下stl的源码,然后用Source Insight这个软件跟踪一下
还是看源码最容易理解,我也得看一下了,不懂的还是很多啊
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
这样说也有点不明白,给你写了个简单点的,代码如下,我只是写个简单的例子,迭代器的实现很麻烦的:
#include iostream
using namespace std;
class _It
{
public:
_It(){}
_It(int *a):p(a){}
int* operator ++(int)
{
int *q=p;
p++;
return q;
}
bool operator =(_It oth)
{
return (this-p)=(oth.p);
}
int operator -(_It oth)
{
return (this-p)-(oth.p);
}
private:
int *p;
};
templateclass T
class myvector
{
public:
myvector(int n,T a)
{
data=new T[n];
for(int i=0;in;i++)
data[i]=a;
len=n;
}
myvector(_It s,_It e)
{
len=e-s;
data=new T[len];
T *p=data;
while(s=e)
*p++=*s++;
}
void print()
{
for(int i=0;ilen;i++)
coutdata[i]" ";
coutendl;
}
private:
T *data;
int len;
};
void main()
{
myvectorint v1( 5, 6 );
v1.print();
int a[] = {1,2,3};
myvectorint v2(a, a+3);
v2.print();
}
==============================================================
int a[] = {1,2,3}; vectorint v(a, a+3);
这种实现不是因为模板,而是因为int *这种指针也是迭代器的一种,就是说
int *可以转化为迭代器,而不是因为模板的类型替换
比如说
class A
{
A(int){}
}
这样的类,是可以这样用的:
如果一个函数的定义是:
void func(A x){}
则调用时可以用:
func(5);
因为A中有转换的构造函数
这里也是一样的,可以用
int a[] = {1,2,3}; vectorint v(a, a+3);
是因为int *可以转化为迭代器,
不知道这样说明白了没有
其实我对stl的机制也有很多不明白的
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vector里面template中的参数和迭代器不是一个吧,如下:
templateclass _Ty, class _A = allocator_Ty
typedef const_iterator _It;
vector(_It _F, _It _L, const _A _Al = _A())
差不多这个意思:
templateclass T
vector(_Iter _First, _Iter _Last)
不会报错