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

C++ 二維動態陣列初始化技巧:模板類與 Proxy 模式實作

     編輯:C++ 入門

在 C++ 開發中,二維陣列的初始化一直是初學者常見的困擾。由於標準 C++ 要求陣列維度必須為編譯期常數,因此無法直接使用變數來定義二維陣列大小,例如 int i=5, j=4; int a[i][j]; 這類代碼會導致編譯錯誤。為了解決此問題,本文介紹一種利用模板類結合 Proxy 模式實現動態二維陣列的方法。

核心問題:靜態陣列的限制

C++ 的內建陣列在編譯階段就需確定記憶體佈局,因此維度必須是常數表達式。若需根據運行時變數決定大小,必須採用動態記憶體分配或封裝類別。

解決方案:模板類 Array2D 與內部 Proxy 類 Array1D

以下代碼展示一個通用的二維陣列模板類,支援任意類型元素,並透過 operator[] 返回一個代表行的 Proxy 物件,實現雙重下標存取 arr[i][j] 的語法糖:

  1. template <class T>
  2. class Array2D {
  3. private:
  4. T* pData; // 一維動態陣列儲存所有元素
  5. int dim1, dim2; // 兩個維度大小
  6. int dim1Index; // 輔助索引
  7. // Proxy 類別:代表單一行,提供第二維度的下標操作
  8. class Array1D {
  9. private:
  10. int length;
  11. T* start;
  12. public:
  13. Array1D(T* s, int len) : start(s), length(len) {}
  14. T& operator[](int index) {
  15. if (index >= length) throw std::out_of_range("第二維度索引越界");
  16. return *(start + index);
  17. }
  18. };
  19. public:
  20. Array2D(int d1, int d2) : dim1(d1), dim2(d2) {
  21. pData = new T[dim1 * dim2];
  22. }
  23. ~Array2D() { delete[] pData; }
  24. Array1D operator[](int index) {
  25. return Array1D(pData + index * dim2, dim2);
  26. }
  27. void print() {
  28. for (int i = 0; i < dim1; ++i) {
  29. for (int j = 0; j < dim2; ++j)
  30. std::cout << *(pData + i * dim2 + j) << ' ';
  31. std::cout << '\n';
  32. }
  33. }
  34. };
  35. int main() {
  36. int rows = 2, cols = 2;
  37. Array2D<int> test(rows, cols);
  38. test[0][0] = 1; test[0][1] = 2;
  39. test[1][0] = 3; test[1][1] = 4;
  40. test.print();
  41. return 0;
  42. }

設計亮點解析

  • Proxy 模式:Array1D 作為中介層,將二維下標轉換為一維記憶體偏移,實現直觀的 [] [] 語法。
  • 邊界檢查:在 Array1D::operator[] 中加入範圍檢查,拋出異常保護記憶體安全。
  • 模板泛型:支援任意類型 T,複用性強。
  • 資源管理:建構函數分配記憶體,解構函數釋放,符合 RAII 原則(此處為簡化省略拷貝/移動語意,實際專案建議補全)。

實務建議

雖然此範例出自《More Effective C++》用於示範 Proxy 模式,但現代 C++ 開發中更推薦使用 std::vector<std::vector<T>> 或 std::vector<T> 配合一維索引計算,或是 C++23 引入的 std::mdspan。若需高效能數值計算,可考慮 Eigen、Armadillo 等專業線性代數庫。

總結

透過模板類與 Proxy 模式,我們成功繞過 C++ 靜態陣列的維度限制,實現了語法自然、類型安全的動態二維陣列。理解此設計有助於掌握 C++ 進階技巧,如運算子重載、Proxy 模式、模板元編程基礎等。

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