萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> 程式語言綜合

C++ 自定義動態數組模板類 MyArray 實現與現代替代方案

教學版實現 (裸指針手動管理)

template <typename T>
class MyArray {
    T* data_ = nullptr;
    size_t size_ = 0;
    size_t capacity_ = 0;

    void reallocate(size_t newCap) {
        T* newData = new T[newCap];
        for (size_t i = 0; i < size_; ++i) newData[i] = std::move(data_[i]);
        delete[] data_;
        data_ = newData;
        capacity_ = newCap;
    }

public:
    MyArray() = default;
    ~MyArray() { delete[] data_; }

    // 複製/移動語義 (規則五)
    MyArray(const MyArray& other) : size_(other.size_), capacity_(other.size_) {
        data_ = new T[capacity_];
        for (size_t i = 0; i < size_; ++i) data_[i] = other.data_[i];
    }
    MyArray& operator=(const MyArray& other) {
        if (this != &other) {
            MyArray tmp(other);
            swap(tmp);
        }
        return *this;
    }
    MyArray(MyArray&& other) noexcept : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
        other.data_ = nullptr; other.size_ = other.capacity_ = 0;
    }
    MyArray& operator=(MyArray&& other) noexcept {
        if (this != &other) { delete[] data_; data_ = other.data_; size_ = other.size_; capacity_ = other.capacity_; other.data_ = nullptr; }
        return *this;
    }
    void swap(MyArray& other) noexcept {
        std::swap(data_, other.data_);
        std::swap(size_, other.size_);
        std::swap(capacity_, other.capacity_);
    }

    // 核心操作
    T& operator[](size_t idx) {
        if (idx >= size_) throw std::out_of_range("index");
        return data_[idx];
    }
    const T& operator[](size_t idx) const { return const_cast<MyArray*>(this)->operator[](idx); }

    void push_back(const T& val) {
        if (size_ == capacity_) reallocate(capacity_ ? capacity_ * 2 : 1);
        data_[size_++] = val;
    }
    void push_back(T&& val) {
        if (size_ == capacity_) reallocate(capacity_ ? capacity_ * 2 : 1);
        data_[size_++] = std::move(val);
    }
    size_t size() const { return size_; }
    bool empty() const { return size_ == 0; }
};

測試代碼

int main() {
    MyArray<int> a;
    a.push_back(11); a.push_back(22); a.push_back(33); a.push_back(55);
    a[0] = 44;
    for (size_t i = 0; i < a.size(); ++i) std::cout << a[i] << '\n';
}

關鍵設計點

要點說明
指數增長容量翻倍 (×2) 攤銷 O(1) 擴容成本
移動語義C++11 push_back(T&&) 避免昂貴拷貝
規則五析構/拷貝構造/拷貝賦值/移動構造/移動賦值 全部實現
異常安全reallocate 先分配再移動,失敗不影響原數據
迭代器教學版省略;生產級需提供 begin/end 支援範圍 for

現代 C++ 最佳實踐:直接用 std::vector

#include <vector>
std::vector<int> v;
v.push_back(11); v.push_back(22); v.push_back(33); v.push_back(55);
v[0] = 44;
for (int x : v) std::cout << x << '\n';
  • std::vector 經過數十年優化:SSO、分配器支援、調試檢查、SIMD 優化、ABI 穩定。
  • 手寫容器僅用於:教學理解 RAII/移動語義、極度受限嵌入式 (禁用 STL)、特殊內存佈局需求。
  • 若需固定容量棧上分配:std::array 或 boost::container::static_vector。
copyright © 萬盛學電腦網 all rights reserved