1. 为什么需要自己实现vector?
作为C++开发者,我们每天都在使用STL中的vector容器,但你真的了解它的内部工作原理吗?当我第一次尝试自己实现vector时,才发现原来这个看似简单的动态数组背后隐藏着这么多精妙的设计。
vector之所以成为C++中最常用的容器,主要因为它结合了数组的高效随机访问和动态扩容的灵活性。标准库中的vector经过多年优化,性能已经非常出色,但理解其底层实现原理对于提升我们的编程能力至关重要。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. vector的基本框架设计
2.1 核心成员变量
任何vector实现都需要三个核心成员变量:
cpp复制template <typename T>
class vector {
private:
T* _data; // 指向动态分配的数组
size_t _size; // 当前存储的元素数量
size_t _capacity; // 当前分配的容量
};
这里有几个关键点需要注意:
_data使用裸指针而不是智能指针,这是为了与标准库实现保持一致_size和_capacity使用size_t类型,确保能表示足够大的值- 模板参数T决定了vector存储的元素类型
2.2 内存管理策略
vector的核心在于其内存管理策略。与静态数组不同,vector会根据需要自动扩容,但扩容操作是有代价的。每次扩容都需要:
- 分配新的更大的内存块
- 将原有元素拷贝到新内存
- 释放旧内存
这种操作的时间复杂度是O(n),因此频繁扩容会严重影响性能。这就是为什么vector通常采用指数级扩容策略(如每次扩容为当前容量的2倍),这样可以将均摊时间复杂度降到O(1)。
3. 构造函数与析构函数实现
3.1 默认构造函数
最简单的构造函数创建一个空vector:
cpp复制vector() : _data(nullptr), _size(0), _capacity(0) {}
这个实现非常直接,但要注意:
- 将指针初始化为nullptr是个好习惯
- 初始容量为0,第一次插入元素时才会分配内存
3.2 带初始值的构造函数
这个构造函数创建包含n个元素的
