C++ STL Vector 底层原理与模拟实现
在之前的讨论中,我们熟悉了 vector 容器的基本用法。今天我们来深入到底层,看看它是如何管理内存的,并尝试自己实现一个简易版。
一、Vector 的基本成员变量
要实现一个 vector,首先得搞清楚它内部维护了哪些指针。通过查阅源码或分析逻辑,我们会发现核心就是三个指针:
_start:指向动态开辟空间的起始位置。_finish:指向当前有效数据的最后一个元素的下一个位置(即尾后迭代器)。_endofstorage:指向整个空间末尾的下一个位置(用于判断是否需要扩容)。
有了这三个指针,vector 的框架就搭好了。下面是一个基础的类定义结构:
#include <iostream>
using namespace std;
namespace my_vector {
template<class T>
class vector {
public:
// 原生指针本身就能完成 ++ * -- 等操作,直接用作迭代器
typedef T* iterator;
typedef const T* const_iterator;
private:
iterator _start; // 指向空间头部的指针
iterator _finish; // 指向最后一个有效数据的下一个位置
iterator _endofstorage; // 指向空间的末尾
};
}
接下来,我们将按照构造、迭代器、空间管理、元素访问、修改操作这五个步骤来完善它。
二、Vector 核心接口的实现
2.1 构造相关接口
构造函数需要处理多种情况:默认构造、指定大小构造、拷贝构造、初始化列表构造以及区间构造。赋值运算符重载也是必不可少的。
注意:模板类的声明和定义必须放在同一个文件中,不能像普通类那样分离到
.h和.cpp。
// 默认构造
vector() : _start(nullptr), _finish(nullptr), _endofstorage(nullptr) {}
// 使用 n 个 val 初始化
// T() 会调用类型 T 的默认构造,支持内置类型和自定义类型
vector(size_t n, T val = ()) {
(n, val);
}
( vector<T>& v) {
(v.());
( e : v) {
(e);
}
}
(initializer_list<T> il) {
(il.());
( e : il) {
(e);
}
}
{
(first != last) {
(*first);
++first;
}
}
vector& =( vector<T>& v) {
(v);
*;
}
{
std::(_start, v._start);
std::(_finish, v._finish);
std::(_endofstorage, v._endofstorage);
}
~() {
(_start) {
[] _start;
_start = _finish = _endofstorage = ;
}
}


