简易vector模板类

难度: 中 | 预计时间: 4-6小时

🎯 项目目标

💻 完整代码

/**
 * 简易vector模板类实现
 * 
 * 功能:
 * - 动态内存管理 (RAII)
 * - 移动语义 (避免深拷贝)
 * - 迭代器支持
 * - emplace_back原地构造
 * 
 * 编译: g++ -std=c++17 -O2 -o myvector myvector.cpp
 */

#include <iostream>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <utility>

template<typename T>
class MyVector {
private:
    T* data_;           // 指向动态数组
    size_t size_;       // 当前元素数量
    size_t capacity_;  // 容量(可存储的最大元素数)

    // 扩容:分配新内存,移动旧元素,释放旧内存
    void grow() {
        size_t new_cap = capacity_ == 0 ? 1 : capacity_ * 2;
        T* new_data = new T[new_cap];
        
        // 移动旧元素到新内存
        for (size_t i = 0; i < size_; i++) {
            new_data[i] = std::move(data_[i]);
        }
        
        // 释放旧内存
        delete[] data_;
        
        data_ = new_data;
        capacity_ = new_cap;
    }

public:
    // ==================== 构造/析构 ====================
    
    // 默认构造
    MyVector() : data_(nullptr), size_(0), capacity_(0) {}
    
    // 带初始大小的构造
    explicit MyVector(size_t count) 
        : data_(new T[count]), size_(count), capacity_(count) {}
    
    // 析构函数 - 释放资源
    ~MyVector() {
        delete[] data_;
    }
    
    // 禁止拷贝(简化实现)
    MyVector(const MyVector&) = delete;
    MyVector& operator=(const MyVector&) = delete;
    
    // 移动构造 - 转移所有权
    MyVector(MyVector&& other) noexcept
        : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
        other.data_ = nullptr;
        other.size_ = 0;
        other.capacity_ = 0;
    }
    
    // 移动赋值
    MyVector& operator=(MyVector&& other) noexcept {
        if (this != &other) {
            delete[] data_;
            data_ = other.data_;
            size_ = other.size_;
            capacity_ = other.capacity_;
            other.data_ = nullptr;
            other.size_ = 0;
            other.capacity_ = 0;
        }
        return *this;
    }

    // ==================== 元素访问 ====================
    
    T& operator[](size_t index) {
        return data_[index];
    }
    
    const T& operator[](size_t index) const {
        return data_[index];
    }
    
    T& at(size_t index) {
        if (index >= size_) throw std::out_of_range("Index out of range");
        return data_[index];
    }

    // ==================== 容量 ====================
    
    size_t size() const { return size_; }
    size_t capacity() const { return capacity_; }
    bool empty() const { return size_ == 0; }

    // ==================== 修改器 ====================
    
    // 在末尾添加元素(移动)
    void push_back(T&& value) {
        if (size_ >= capacity_) grow();
        data_[size_++] = std::move(value);
    }
    
    // 在末尾添加元素(拷贝)
    void push_back(const T& value) {
        if (size_ >= capacity_) grow();
        data_[size_++] = value;
    }
    
    // emplace_back: 原地构造元素(避免临时对象)
    template<typename... Args>
    T& emplace_back(Args&&... args) {
        if (size_ >= capacity_) grow();
        new (&data_[size_]) T(std::forward<Args>(args)...);
        return data_[size_++];
    }
    
    void pop_back() {
        if (size_ > 0) {
            data_[--size_].~T();
        }
    }

    // ==================== 迭代器 ====================
    
    T* begin() { return data_; }
    T* end() { return data_ + size_; }
    const T* begin() const { return data_; }
    const T* end() const { return data_ + size_; }
};

// ==================== 测试 ====================
int main() {
    // 基本使用
    MyVector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    
    // range-for循环(需要迭代器)
    std::cout << "Elements: ";
    for (auto& x : v) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // emplace_back原地构造
    struct Point { int x, y; };
    MyVector<Point> points;
    points.emplace_back(10, 20);  // 直接构造,无临时对象
    points.emplace_back(30, 40);
    
    std::cout << "Point: (" << points[0].x << ", " << points[0].y << ")" << std::endl;
    
    // 移动语义
    MyVector<int> v2 = std::move(v);  // v的所有权转移给v2
    std::cout << "v2 size: " << v2.size() << std::endl;
    std::cout << "v size: " << v.size() << " (moved)" << std::endl;
    
    return 0;
}

📝 关键知识点详解

1. RAII (Resource Acquisition Is Initialization)

2. 移动语义

3. emplace_back vs push_back

4. 完美转发

💡 扩展任务: