C++自定义(手撕)vector类实现过程
作者:Truelon
文章介绍了C++中std::vector的简化实现,涵盖模板类定义、动态数组管理、构造析构函数、深拷贝机制、迭代器及容量操作等核心内容,旨在通过手动实现理解其内存管理原理和底层实现逻辑
引言
在C++中,std::vector
是一个非常强大的容器,能够自动管理其内部存储空间的大小,使得程序员无需手动处理内存分配和释放。然而,理解 std::vector
内部工作原理对于提高编程技能至关重要。
通过自己实现一个简化版的 vector
类,我们可以更好地掌握其背后的核心概念。
类定义与成员变量
我们首先定义了一个模板类 vector
,它接受一个类型参数 T
。此外,我们定义了三个成员变量:
_data
:指向动态分配的数组的指针。_size
:当前元素的数量。_capacity
:分配的数组可以容纳的最大元素数量。
template<typename T> class vector { public: // ... 公共接口 ... private: T* _data; size_t _size; size_t _capacity; };
构造函数
- 默认构造函数:初始化
_data
为nullptr
,_size
和_capacity
为0
。 - 带参数构造函数:接收一个元素数量和可选的初始值,创建一个初始化了特定数量元素的
vector
。 - 拷贝构造函数:执行深拷贝,确保每个
vector
对象都有自己的数据副本。
vector() : _data(nullptr), _size(0), _capacity(0) {} explicit vector(size_t count, const T& value = T()) { /* 初始化逻辑 */ } vector(const vector& vec) { /* 深拷贝逻辑 */ }
析构函数
析构函数负责释放由 _data
指向的动态分配的内存。
~vector() { delete[] _data; }
深拷贝构造函数与赋值操作
为了防止浅拷贝导致的问题(例如,多个 vector
对象指向同一块内存),我们实现了深拷贝构造函数和赋值操作符。
vector(const vector& vec) { /* 深拷贝逻辑 */ } vector& operator=(const vector& vec) { /* 深拷贝赋值逻辑 */ }
迭代器
提供 begin()
和 end()
方法来获取指向向量起始和结束位置的迭代器,分别用于非常量和常量上下文。
T* begin() { return _data; } T* end() { return _data + _size; } const T* begin() const { return _data; } const T* end() const { return _data + _size; }
容量与大小
size()
返回当前元素数量,而 capacity()
返回数组的最大容量。
size_t size() const { return _size; } size_t capacity() const { return _capacity; }
元素操作
push_back()
和 pop_back()
用于在向量末尾添加或移除元素。insert()
和 erase()
用于在任意位置插入或删除元素。
void push_back(T val); void pop_back(); void insert(size_t index, const T& value); void erase(size_t index);
辅助函数
resize()
函数用于在必要时调整向量的容量。
void resize(size_t new_capacity);
完整代码
#include <iostream> #include <vector> // 定义一个名为mv的命名空间 namespace mv { // 定义一个模板类vector template<typename T> class vector { public: // 定义类型别名 typedef T val_type; typedef val_type* iterator; // 默认构造函数 vector() : _data(nullptr), _size(0), _capacity(0) {} // 析构函数,用于释放动态分配的内存 ~vector() { delete[] _data; } // 带参数的构造函数,初始化vector大小和默认值 explicit vector(size_t count, const val_type& value = val_type()) : _data(new val_type[count]), _size(count), _capacity(count) { for (size_t i = 0; i < count; ++i) { _data[i] = value; } } // 深拷贝构造函数,避免浅拷贝的问题 vector(const vector& vec) { _capacity = vec._capacity; _data = new val_type[_capacity]; // 分配新的内存空间 for (size_t i = 0; i < vec._size; ++i) { _data[i] = vec._data[i]; } _size = vec._size; } // 提供const和非const版本的begin和end方法 iterator begin() { return _data; } iterator end() { return _data + _size; } iterator begin() const { return _data; } iterator end() const { return _data + _size; } // 返回vector的大小和容量 size_t size() const { return _size; } size_t capacity() const { return _capacity; } // 在末尾添加一个元素 void push_back(val_type val) { if (_size == _capacity) { resize(_capacity == 0 ? 1 : _capacity * 2); } _data[_size++] = val; } // 移除最后一个元素 void pop_back() { if (_size > 0) --_size; } // 在指定位置插入一个元素 void insert(size_t index, const val_type& value) { if (_size == _capacity) { resize(_capacity == 0 ? 1 : _capacity * 2); } if (index > _size) { std::cout << "Index out of range in insert()"; } for (size_t i = _size; i > index; --i) { _data[i] = _data[i - 1]; } _data[index] = value; ++_size; } // 删除指定位置的元素 void erase(size_t index) { if (index >= _size) { std::cout << "Index out of range in erase()"; } for (size_t i = index; i < _size - 1; ++i) { _data[i] = _data[i + 1]; } --_size; } // 判断vector是否为空 bool empty() { return _size == 0; } // 下标操作符,返回指定位置的元素 val_type& operator[](size_t index) { return _data[index]; } // 比较两个vector是否相等 bool operator==(const vector& vec) const { if (_size != vec._size) return false; for (size_t i = 0; i < _size; ++i) { if (_data[i] != vec._data[i]) return false; } return true; } // 赋值操作符,实现深拷贝 vector& operator=(const vector& vec) { if (this != &vec) { // 防止自赋值 delete[] _data; // 释放原有资源 _capacity = vec._capacity; _data = new val_type[_capacity]; // 分配新资源 for (size_t i = 0; i < vec._size; ++i) { _data[i] = vec._data[i]; } _size = vec._size; } return *this; } private: // 调整vector的容量 void resize(size_t new_capacity) { val_type* new_data = new val_type[new_capacity]; for (size_t i = 0; i < _size; ++i) { new_data[i] = _data[i]; } delete[] _data; _data = new_data; _capacity = new_capacity; } // 成员变量 val_type* _data; size_t _size; size_t _capacity; }; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。