markdown复制## 1. 从零实现STL vector容器:深入理解动态数组设计
在C++标准模板库中,vector是最常用的序列式容器之一。作为动态数组的实现,它完美平衡了数组的随机访问特性和动态扩容能力。本文将带你从零开始实现一个简化版vector,重点解析其核心设计思想和关键实现细节。
### 1.1 vector的核心设计理念
vector的底层实现基于三个关键指针:
- `_start`:指向动态数组的首元素
- `_finish`:指向最后一个有效元素的下一个位置
- `_end_of_storage`:指向已分配内存的末尾
这种设计有三大优势:
1. 通过指针差值可快速计算size和capacity
2. 迭代器就是原生指针,零额外开销
3. 内存管理直观高效
```cpp
template <class T>
class vector {
protected:
T* _start; // 首元素指针
T* _finish; // 末尾后位置
T* _end_of_storage; // 容量末尾
};
1.2 迭代器实现解析
vector的迭代器直接使用原生指针实现,这是其高效的关键:
cpp复制typedef T* iterator;
typedef const T* const_iterator;
iterator begin() { return _start; }
iterator end() { return _finish; }
这种设计使得:
- 迭代器操作完全等同于指针操作
- 支持随机访问(+=, -=等操作)
- 与C风格数组完美兼容
关键细节:const迭代器通过类型系统保证数据不可修改,是设计const正确性的典范。
2. 核心接口实现详解
2.1 内存管理实现
2.1.1 reserve扩容机制
reserve是vector性能的关键,需要特别注意深拷贝问题:
cpp复制void reserve(size_t n) {
if (n > capacity()) {
size_t sz = size();
T* tmp = new T[n];
// 必须使用元素拷贝而非memcpy
for(size_t i=0; i<sz; ++i) {
tmp[i] = _start[i]; // 调用元素的operator=
}
delete[] _start;
_start = tmp;
_finish = _start + sz;
_end_of_storage = _start + n;
}
}
典型错误案例:
cpp复制// 错误示范:会导致浅拷贝问题
memcpy(tmp,
