Bootstrap

C++ 自定义 Vector 类实现详解

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;
};

构造函数

  • 默认构造函数:初始化 _datanullptr_size_capacity0
  • 带参数构造函数:接收一个元素数量和可选的初始值,创建一个初始化了特定数量元素的 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;
    };
}
;