C++ 自定义 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;
};
}