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;
};
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
