Vector和array相似,差别在于空间运用的灵活性。Array是静态空间,一经设置不能改变;vector是动态空间,随着元素的加入,会自行扩充空间以容纳新元素。
Vector维护的是一个线性连续空间,普通的指针就可以作为vector的迭代器满足所有的必要条件。Vector支持随机存储,普通指针也有这样的能力,vector提供的是random access iterators。
Template <class T,class Alloc=alloc>
class vector
{
public :
typedefT value_type;
//vector的迭代器是指针
typedef value_type* iterator;
};
如果出现这样的代码:
vector <int> ::iterator ivite;
vector <Shape>::iterator svite;
表示 ivite的型别是int*,svite的型别是Shape*。
vector的数据结构:线性连续空间。
Template <class T,class Alloc=alloc>
class vector
{
....
protected:
//表示使用空间的头
iterator start;
//表示目前使用空间的尾部
iterator finsh;
//表示目前可用空间的尾部
iterator end_of_storage;
};
Template <class T,class Alloc=alloc>
class vector
{
public :
//嵌套类型定义
typedef T value_type;
typedefvalue_type* pointer;
typedefvalue_type* iterator;
typedefvalue_type& reference;
typedefsize_t size_type;
typedefptrdiff_t difference_type;
protected:
typedef simple_alloc<value_type,Alloc>data_allocator;
iteratorstart;//目前使用空间的头
iteratorfinish;//目前使用空间的尾部
iteratorend_of _storage;//目前可用空间的尾部
voidinsert_aux(iterator position,const T&x);
/*
*c++中destroy() deallocate() delete()的区别
* destroy()显示调用一个对象的析构函数,相当于释放一个对象需要释放的动态内存
*为下次真正释放内存做准备
*deallocate()真正释放一个内存块,是一个上层封装,是dolete()函数的上层封装。
*在stl空间配置器中,有可能会调用delete还给OS,,但也有可能放在内存池中,对
*用户来说就是释放内存块
* #include <iostream>
* #include <stdlib.h>
* #include <unistd.h>
* using namespace std;
* class A
* {
* public:
* A()
* {
* data=new char[1000000];
* }
* ~A()
* {
* //free the data memory
* delete []data;
* }
* private:
* char *data;
* };
* int main(int argc,char* argv[])
* {
* for(;;)
* {
* A *a=new A;
* std::allocator<A> allocat;
* allocat.deallocate(a,sizeof(A));
*
* }
* return 0;
* }
**/
/* 明显这样的做法会出问题,运行到一定的时间内会抛出异常。
所以deallocate只是释放对象内存,并没有调用对象的构造函
数释放对象内的动态内存 这点要注意
如果调用了一个 allocat.destory(a); 程序就不会有bug了 */
/* 在C++中, 对象释放和对象内动态内存释放是需要注意的
弄不好就会出现内存泄露现象。 */
/* delete操作符号本身带有2个动作:调用析构函数 2释放内存
而::operator delete就只有释放内存
deallocate函数就是基于operator delete函数封装的 */
/* 像vector()的析构函数都是有2个操作:
destory() 释放对象内的动态内存(如果有)
deallocate是释放对象本身占有的内存
通过这2点 就能保证内存不能泄露了 */
/* 通俗的说就是释放内存要释放对象内存和动态内存而deallocate释放的是对象本身的内存
destroy()释放的是对象的动态内存。两者要结合起来 */
voiddeallocate(){
if (start)
data_allocator::deallocate(start,end_of_storage-start);
}
fill_initialize(size_typen,const T &value){
start=allocate_and_fill(n,value);
finish=start+n;
end_of_storage==finish;
}
public :
iterator begin(){return start;}
iteratorend(){return finish;}
size_typesize()const{return size_type(end()-begin());}
size_typecapacity()const{return size_type(end_of_storage-begin());}
boolempty()const{return end()==begin();}
referenceoperator[]()(size_type n){return *(begin()+n);}
referencefront(){return *begin();}
referenceback(){return *(end()-1);}//end超过结尾 指最后一个对象后面的一个对象
//构造函数
vector():start(0),finish(0),end_of_storage(0){}
vector(size_typen,const T& value){fill_initialize(n,value);}
vector(intn,const T& value){fill_initialize(n,value);}
vector(longn,const T &value){fill_initialize(n,value);}
explicitvector(size_type n){fill_initialize(n,T());}
~vector()
{
destroy(begin(),end());
deallocate();
}
//操作
voidpush_back(const T& x){//将元素插入到最为段
if(finish!=end_of_storage)
/* #include <new.h>
Template<class T1,class T2>
inline construct(T1 *p,T2 &value)
{new(p) T1(value);}//placement new:调用T1::T1(value)
construct()接受一个指针和一个初值,将初值设定在指针所指的位置上 */
construct(finish,x);
++finish;
else
insert_aux(end(),x);}
void pop_back()//将尾端元素取出
{
finish--;
destroy (finish);
}
iteratorerase(iterator position){//删除某个位置上的元素
if(position+1!=end())
/* template<class InputIterator,class OutIterator>
OutIterator copy(InputIterator_First,OutIterator _Last,OutIterator _DestBeg);
_First,_Last复制的区间范围 _DestBeg复制到的目标区间的起始位置 */
copy(position+1,finish,position);
--finish;
destroyfinish;
returnposition;}
voidresize(size_type new_size,const T& x){
if(new_size<size())
erase(begin()+new_size,end());
else
insert(end(),new_size-size(),x); }
voidresize(size_type new_size){
resize(new_size,T());}
voidclear(){erase(begin(),end());}
pretocted:
iterator allocate_and_fill(size_type n,const T& x){
iterator result=data_allocator::allocate(n);
uninitialized_fill_n(result,n,x);
return result;
};