您的位置:首页 > 其它

STL_学习_vector容器源码解析

2016-05-05 21:54 423 查看
这里自己总结了自己对SGI的vector容器的操作原理的一点理解。

#ifndef _STL_VECTOR_H_

#define _STL_VECTOR_H_

template<class T, class Alloc=alloc>

class vector{

public:

typedef T value_type;

typedef value_type* pointer;

typedef const value_type* const_pointer;

typedef value_type* iterator;

typedef const value_type* const_iterator;

typedef value_type& reference;

typedef const value_type& const_reference;

typedef size_t size_type;

typedef ptrdiff_t difference_type;

protected:

//定义一个空间配置器,以元素大小为配置单位,也就是value_type类型的大小为配置单位

typedef simple_alloc<value_type, Alloc> data_allocator;

//目前使用空间的头

iterator start;

//目前使用空间的尾

iterator finish;

//目前可用空间的尾

iterator end_of_storage;

//负责释放空间

void deallocate()

{

if(start){

data_allocator::deallocate(start, end_of_storage - start);

}

}

//填充空间并且进行初始化

void fill_initialize(size_type n, const T& value)

{

start = allocate_and_fill(n, value);

finish = start + n;

end_of_storage = finish;

}

iterator allocate_and_fill(size_type n, const T& x)

{

iterator result = data_allocator::allocate(n);

uninitialized_fill_n(result, n, x);

return result;

}

//以下是vector容器提供的相应的接口,这里没有写全

public:

iterator begin(){return start;}//返回容器的起始位置

iterator end(){return finish;}//返回容器的结束位置

size_type size(){return size_type(end() - begin());}//使用空间的大小

//返回容器的大小

size_type capacity()const

{

return size_type(end_of_storage - begin());

}

bool empty()const{return begin() == end();}

//重载[]就可以进行下标的访问

reference operator[](size_type n){return *(begin() + n);}

public:

//5个构造函数的重载

vector():start(0),finish(0),end_of_storage(0){}

vector(size_type n, const T& value)

{

fill_initialize(n, value);

}

vector(int n, const T& value){fill_initialize(n, value);}

vector(long n, const T& value){fill_initialize(n, value);}

vector(size_type n){fill_initialize(n, T());}

~vector()

{

destroy(start, finish);

deallocate();

}

reference front(){return *begin();}//返回容器第一个元素的值

reference back(){return *(end() - 1);}

//尾插

void push_back(const T & x)

{

if(finish != end_of_storage){

construct(finish, x);

++finish;

}

//如果空间不足则调用insert_aux()

else{

insert_aux(end(), x);

}

}

//尾删,这里注意尾删只是将最后一个元素删除但是空间并没有释放

void pop_back()

{

--finish;

destory(finish);

}

//删除范围内的元素

iterator erase(iterator first, iterator last)

{

iterator i = copy(last, finish, first);

destory(i, finish);

finish = finish - (last - first);

return first;

}

//删除某个位置上的元素(将删除位置后面的元素直接往前移动覆盖掉要删除的元素即可)

iterator erase(iterator position)

{

if(position + 1 != end()){

copy(position + 1, finish, position);

}

--finish;

destory(finish);

return position;

}

//清空容器

void clear()

{

erase(begin(), end());

}

//插入

void insert(iterator position, size_type n, const T & x);

};

template<class T, class Alloc>

void vector<T, Alloc>::insert_aux(iterator position, const T& x)

{

if(finish != end_of_storage){

construct(finish, *(finish - 1));

++finish;

T x_copy = x;

copy_backward(position, finish - 2, finish - 1);

*position = x_copy;

}

//没有空间则扩充空间(申请新的空间大小为旧空间的2倍,拷贝元素到新空间,释放旧空间)

else{

const size_type old_size = size();

const size_type len = old_size != 0?2 * old_size : 1;

iterator new_start = data_allocator::allocate(len);

iterator new_finish = new_start;

new_finish = uninitialzed_copy(start, position, new_start);

construct(new_finish, x);

++new_finish;

new_finish = uninitialzed_copy(position, finish, new_finish);

}

destory(begin(), end());

deallocate();

start = new_start;

finish = new_finish;

end_of_storage = new_start + len;

}

//这里的插入操作分为2类

//(1)有足够的空间

// (1)判断插入的元素个数如果小于插入点之后的元素个数,先确定新的finish,然后再将插入

// 点后面的元素拷贝到old_finish,最后填充要插入的元素

// (2)插入的元素个数大于等于插入点之后的元素个数,先将要插入的元素的结束位置固定好,

// 然后将插入点以后的元素拷贝到之前固定好的结束位置处,最后填充要插入的元素


//(2)空间不足

template<class T, class Alloc>

void vector<T, Alloc>::insert(iterator position, size_type n, T& x)

{

if(n != 0){

if(n < (size_type)(end_of_storage - finish)){

T x_copy = x;

const size_type elems_after = finish - position;

iterator old_finish = finish;

if(elems_after > n){

uninitialized_copy(finish - n, finish, finish);

finish += n;

copy_backward(position, old_finish - n, old_finish);

fill(position, position + n, x_copy);

}

else{

uninitialized_fill_n(finish, n - elems_after, x_copy);

finish += n - elems_after;

uninitialized_copy(position, old_finish, finish);

finish += elems_after;

fill(position, position + n, x_copy);

}

}

else{

const size_type old_size = size();

const size_type len = old_size != 0?2*old_size:1;

iterator new_start = data_allocator::allocate(len);

iteratoe new_finish = new_start;

new_finish = uninitialized_copy(start, position, new_start);

new_finish = uninitialized_fill_n(new_finish, n, x);

new_finish = uninitialized_copy(position, finish, new_finish);

destory(start, finish);

deallocate();

start = new_start;

finish = new_finish;

end_of_storage = finish + len;

}

}

}

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: