首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 二維動態陣列類模板實現:模板與運算符重載的工程實踐

     編輯:關於C++

前言

C++ 模板與運算符重載是實現泛型容器的利器。本文展示一套完整的一維/二維動態陣列類模板,支援任意型別、邊界檢查、拷貝語意、串流輸出與直觀的 arr[i][j] 存取語法。

一、設計架構

  • Array<T>:一維動態陣列基礎類別
  • Array2D<T>:二維陣列,內含 Array<T> 扁平化儲存,巢狀 RowArray 代理類別實現 [] 雙重下標

二、核心實現亮點

1. Array<T> 關鍵特性

  • 多種建構函數:預設大小、可變參數初始化、拷貝建構
  • 規則五 (Rule of Five):解構子、拷貝建構、拷貝指派、移動語意 (C++11 可擴充)
  • 雙重 operator[]:可變版本回傳 T&,const 版本回傳 const T&
  • 邊界檢查:越界拋出 std::out_of_range
  • 串流輸出:friend operator<<
  • 動態調整大小:setSize() 保留資料

2. Array2D<T> 代理模式實現 arr[row][col]


// 巢狀代理類別
class RowArray {
private:
    const Array2D<T>& array2D;
    unsigned int row;
public:
    RowArray(Array2D<T>& a, unsigned int r) : array2D(a), row(r) {}
    RowArray(const Array2D<T>& a, unsigned int r) : array2D(a), row(r) {}
    
    T& operator[](unsigned int col) {
        if (col >= array2D.cols) throw out_of_range("invalid col");
        return const_cast<Array2D<T>&>(array2D).array[row * array2D.cols + col];
    }
    const T& operator[](unsigned int col) const {
        if (col >= array2D.cols) throw out_of_range("invalid col");
        return array2D.array[row * array2D.cols + col];
    }
};

// Array2D 雙重下標
RowArray operator[](unsigned int row) {
    if (row >= rows) throw out_of_range("invalid row");
    return RowArray(*this, row);
}
const RowArray operator[](unsigned int row) const {
    if (row >= rows) throw out_of_range("invalid row");
    return RowArray(*this, row);
}

關鍵點:RowArray 持有外層參考,透過 row * cols + col 計算扁平化索引,const_cast 處理可讀/可寫版本。

三、完整標頭檔

Array.h


#ifndef CARL_SEN_ARRAY_H
#define CARL_SEN_ARRAY_H
#include <iostream>
#include <cstdarg>
#include <stdexcept>
using std::out_of_range;
using std::ostream;

template<typename T>
class Array {
    unsigned int size;
    T* data;
public:
    Array(unsigned int _size = 0);
    Array(unsigned int count, T data1, ...);
    Array(const Array<T>& array);
    Array& operator=(const Array<T>& array);
    ~Array() { delete[] data; }
    
    T& operator[](unsigned int index);
    const T& operator[](unsigned int index) const;
    friend ostream& operator<<(ostream& os, const Array<T>& array);
    
    unsigned int getSize() const { return size; }
    void setSize(unsigned int newSize);
};
// ... 實現略 (見原始碼)
#endif

Array2D.h


#ifndef CARL_SEN_ARRAY2D_H
#define CARL_SEN_ARRAY2D_H
#include "Array.h"
#include <iostream>
#include <cstdarg>
#include <stdexcept>
using std::ostream;
using std::out_of_range;

template <typename T>
class Array2D {
    unsigned int rows, cols;
    Array<T> array;  // 扁平化儲存
public:
    Array2D(unsigned int _rows = 0, unsigned int _cols = 0);
    Array2D(unsigned int _rows, unsigned int _cols, T data1, ...);
    
    class RowArray;  // 前向宣告
    RowArray operator[](unsigned int row);
    const RowArray operator[](unsigned int row) const;
    friend ostream& operator<<(ostream& os, const Array2D<T>& array2D);
    
    unsigned int getRows() const { return rows; }
    unsigned int getCols() const { return cols; }
    
    class RowArray { /* ... 見上方 ... */ };
    friend class RowArray;
};
// ... 實現略
#endif

四、測試程式與輸出驗證


#include "Array.h"
#include "Array2D.h"
#include <iostream>
#include <string>

void testArray() {
    Array<int> a1(3);
    a1[0]=1; a1[1]=2; a1[2]=3;
    cout << a1 << endl;  // 1  2  3
    
    const Array<int> a2(3, 123, 234, 345);  // 可變參數建構
    Array<int> a3(a1);  // 拷貝建構
    Array<int> a5; a5 = a4;  // 拷貝指派
    a5.setSize(4); a5[3] = 111;  // 動態擴充
    
    Array<string> a6(2, string("str0"), string("str1"));  // 非 POD 型別
}

五、現代 C++ 改進建議 (C++11/14/17/20)

原始做法現代替代優勢
可變參數 va_list可變參數模板 / std::initializer_list型別安全、編譯期檢查
手動 new[]/delete[]std::vector<T> / std::unique_ptr<T[]>RAII、例外安全
拋出 out_of_range可選:assert / std::optional / Contracts (C++26)效能/風格選擇
自定義串流輸出std::format (C++20) / ranges標準化格式化

六、總結

此實現展示了模板、運算符重載、代理類別、記憶體管理等核心 C++ 技術的綜合運用。雖然現代 C++ 標準庫提供了 std::vector、std::array、std::mdspan (C++23) 等更完善的工具,但理解底層實現機制對於深度掌握 C++ 系統程式設計至關重要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved