1. 为什么需要模拟实现vector
在C++标准库中,vector是最常用的容器之一,它提供了动态数组的功能。但很多开发者只是停留在"会用"的层面,对底层实现机制一知半解。最近我在面试候选人时发现,能准确说出vector扩容机制的人不到30%。
自己动手实现一个简化版的vector,是深入理解STL容器的最佳途径。通过这个过程,你会真正掌握:
- 动态内存管理的核心原理
- 迭代器失效的底层原因
- 异常安全保证的实现方式
- 模板编程的实际应用
我建议每个C++开发者都应该至少实现一次vector。下面分享我的实现过程和关键要点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础框架搭建
2.1 类模板定义
首先定义我们的Vector类模板框架:
cpp复制template <typename T>
class Vector {
public:
// 类型别名
using value_type = T;
using pointer = T*;
using reference = T&;
using const_reference = const T&;
using size_type = size_t;
using difference_type = ptrdiff_t;
// 迭代器类型(简化版随机访问迭代器)
class iterator {
// 迭代器实现细节...
};
// 构造函数/析构函数
Vector();
explicit Vector(size_type count, const T& value = T());
Vector(const Vector& other);
~Vector();
// 容量相关
size_type size() const;
size_type capacity() const;
bool empty() const;
// 元素访问
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
reference at(size_type pos);
const_reference at(size_type pos) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
// 修改操作
void push_back(const T& value);
void pop_back();
iterator insert(iterator pos, const T& value);
iterator erase(iterator pos);
void clear();
void reserve(size_type new_cap);
void resize(size_type count, const T& value = T());
private:
T* m_data = nullptr; // 数据存储指针
size_type m_size = 0; // 当前元素数量
size_type m_capacity = 0; // 当前分配的内存容量
};
关键点:模板参数T表示元素类型,m_data指向动态分配的内存,m_size和m_capacity分别记录当前元素数量和总容量。
2.2 内存管理策略
vector的核心在于动态内存管理。我们的实现采用经典的"两倍扩容"策略:
- 初始分配少量内存(比如4个元素)
- 当空间不足时,分配原来两倍大小的新内存
- 将旧元素移动到新内存
- 释放旧内存
这种策略在时间复杂度和空间利用率之间取得了较好的平衡。虽然可能造成最多50%的内存浪费,
