本文共 4262 字,大约阅读时间需要 14 分钟。
在C++编程中,vector 是标准库中最常用的动态数组实现之一。通过阅读和分析其官方文档,可以深入了解 vector 的各个成员函数及其实现原理。本文将从构造函数、成员变量、拷贝与赋值操作、析构函数以及其他相关函数等方面详细解析 vector 的实现逻辑。
为了避免与标准库中的 vector 类产生命名冲突,建议将模拟实现放在自己的命名空间中。这样可以确保代码的唯一性并避免潜在的问题。
namespace cl { // 模拟实现vector template template class vector { public: // 其他成员函数定义 };} vector 类的实现中维护三个关键成员变量:
_start:指向容器的头。_finish:指向容器中有效数据的尾。_endofstorage:指向整个容器的尾。通过这些指针,可以轻松获取容器的大小和容量:
size_t size()const { return _finish - _start; }size_t capacity()const { return _endofstorage - _start; } 无参构造函数用于初始化空容器:
vector() : _start(nullptr), _finish(nullptr), _endofstorage(nullptr) {} 支持从其他 vector 或输入迭代器中初始化容器。传统实现方式为:
vector(const vector& v) : _start(nullptr), _finish(nullptr), _endofstorage(nullptr) { _start = new T[v.size()]; for (size_t i = 0; i < v.size(); ++i) { _start[i] = v[i]; } _finish = _start + v.size(); _endofstorage = _start + v.capacity();}
现代写法推荐使用范围遍历:
vector(const vector& v) : _start(nullptr), _finish(nullptr), _endofstorage(nullptr) { reserve(v.capacity()); for (auto e : v) { push_back(e); }}
reserve 函数预分配空间以提高效率。int),直接使用 memcpy 是可行的。string),必须通过 push_back 或其他拷贝机制确保深拷贝。vector& operator=(const vector & v) { if (this != &v) { delete[] _start; _start = new T[v.capacity()]; for (size_t i = 0; i < v.size(); ++i) { _start[i] = v[i]; } _finish = _start + v.size(); _endofstorage = _start + v.capacity(); } return *this;}
vector& operator=(const vector & v) { swap(*this, v); return *this;}
现代写法通过交换两个对象的成员变量来实现赋值操作。
memcpy 函数不能用于深拷贝类型(如 string),因为会导致多个对象共享同一数据。~vector() { if (_start) { delete[] _start; _start = nullptr; _finish = nullptr; _endofstorage = nullptr; }} typedef T* iterator;typedef const T* const_iterator;
iterator begin() { return _start; }iterator end() { return _finish; }const_iterator begin()const { return _start; }const_iterator end()const { return _finish; } for (auto e : v) { // 遍历每个元素} void reserve(size_t n) { if (n > capacity()) { size_t sz = size(); T* tmp = new T[n]; if (_start) { for (size_t i = 0; i < sz; ++i) { tmp[i] = _start[i]; } delete[] _start; } _start = tmp; _finish = _start + sz; _endofstorage = _start + n; }} void resize(size_t n, const T& val = T()) { if (n < size()) { _finish = _start + n; } else { if (n > capacity()) { reserve(n); } while (_finish < _start + n) { *_finish = val; _finish++; } }} void push_back(const T& x) { if (_finish == _endofstorage) { size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity(); reserve(newcapacity); } *_finish = x; _finish++;} void pop_back() { assert(!empty()); _finish--;} void insert(iterator pos, const T& x) { if (_finish == _endofstorage) { size_t len = pos - _start; size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity(); reserve(newcapacity); pos = _start + len; } while (pos + 1 <= _finish) { _finish--; _finish++; } *pos = x; _finish++;}iterator erase(iterator pos) { assert(!empty()); iterator it = pos + 1; while (it != _finish) { _finish--; it++; } _finish--; return pos;} void swap(vector& v) { swap(_start, v._start); swap(_finish, v._finish); swap(_endofstorage, v._endofstorage);}
T& operator[](size_t i) { assert(i < size()); return _start[i];}const T& operator[](size_t i)const { assert(i < size()); return _start[i];} 通过对 vector 类的详细解析,可以看出其设计目标是提供一个高效且灵活的动态数组实现。理解其内部逻辑对优化代码性能至关重要。
转载地址:http://seefk.baihongyu.com/