前言
在STL编程中, 容器就是我们经常会用到的, 容器分为序列容器和关联式容器. 而这一篇我们就分析序列容器之一vector
. 关于用过vector
三的人肯定对其一点都不陌生, vector
基本能够支持任何类型的对象, 同时是一个可以动态增长数组. 马上就来分析关于vector
是怎么实现这些功能.
vector的简单例子
相信都对vector有一定的认识, 这里我就将本节会讲到关于vector
源码的操作执行一次, 让大家先有一个回忆.
int main()
{
vector<int> v1;
vector<int> v2(4);
vector<int> v3(4, 1);
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
if(!v1.empty()) // 不为空
{
cout << *v1.begin() << " " << v1.front() << " " << *(v1.end() - 1) << " " << v1.back() << endl;
cout << "size = " << v1.size() << endl;
v1.~vector();
}
exit(0);
}
输出:
1 1 4 4
size = 4
回忆了vector最基本的操作, 现在我们就来分析其实现.
vector容器
vector基本数据结构
vector
为自己定义嵌套型别. 为了符合traits
编程规则( 规则要求每个使用traits
萃取器的都必须自己定义五个嵌套型别 ), 有一点很重要, vector
迭代器就是一个普通指针. 普通类型可以有不同于其他类型的操作, 比如uninitialized_copy
可以尽可能的优化执行等. 因为vector
必须是存放一个连续的现行空间中, 并且连续空间的大小都要比用户自己要求的空间要大两倍, 剩余的空间是留着作备用, 毕竟vector
可是能动态增长的, 所以留着部分空间以备增长. 这里也可以发现vector
很大的问题, 当以备空间也用完之后, vector
需要重新更大的申请空间然后释放掉之前的空间, 这样的代价也很大啊, 但是为了动态增长, 这点问题我们也可以接受的.
template <class T, class Alloc = alloc>
class vector
{
public:
// 定义vector自身的嵌套型别
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;