在使用二維數組時,我們可以使用a[][]來訪問數組中的元素,這很顯然是正確的也無需證明。
但如果要自己實現一個二維數組的時候,會發現如果想要重載符號[][],會被告知沒有這個符號,這即引出了C++ oop設計方式中的一種proxy class方式。
proxy class即在一個class中,嵌套的聲明了另一個class,利用了這個隱藏的嵌套class以實現一些特殊技巧。
回到二維數組中來,我們已知沒有[][]這種鏈式訪問結構的符號,但是C++又允許我們這樣做,顯然它實現時有某種技巧。
把二維數組拆分來看,其中我們知道,a[posi]是合法的,而我們常用的是a[posi1][posi2],把前半段拆開來看就是
( a[posi1] ) [posi2]
也就是說並沒有什么二維數組,實際上是兩個一維數組,其中第一個一維數組中保存了一些一維數組對象,內部的一維數組中保存了一個數
對應關系即:a[posi] –> _array(一個隱藏的對象) –> _array[posi2] 保存了一個值
以下是一個簡略的代碼實現(有BUG,見后方)
template<typename T> class Array2D { private: //the proxy class class Array1D { private:int _cap = 10; T* _elemNum = new T[_cap]; public: Array1D(int inx) { _elemNum = new T[inx]; } T& operator [](int posi) { return _elemNum[posi]; } const T& operator [](const int posi) const { return _elemNum[posi]; } }; const int _cap = 10; Array1D* _elemArray = new Array1D[_cap]; public: Array2D(int inx1, int inx2) { Array1D* _elemArray = new Array1D[inx1]; for (int i = 0; i < inx1; i++) { Array1D* _tmpArray = new Array1D[inx2]; _elemArray[i] = *_tmpArray; } } Array1D& operator [](int posi) { return _elemArray[posi]; } };
區分兩種數組:_elemArray用於儲存匿名的函數對象,_elemNum用於儲存實際的值。
proxy class在此處的實際意義就在於,其實現只在另一個class內使用,也只提供給他使用,類似於class的一個代理一樣,負責處理內部事務。
注意其中Array2D的重載[]函數:
Array1D& operator [](int posi) { return _elemArray[posi]; }
返回的是一個Array1D對象的引用,那么實際調用時:
a[inx1][inx2] = …; a[inx1]部分返回了一個Array1D對象,為了方便現假定其名稱為_array 故有:
a[inx1][inx2] –> _array[inx2]
同時這里還需要引出一個BUG,當這段代碼實際運行的時候會提示:Array1D沒有合適的默認構造函數可用,解決辦法是給Array1D類一個沒有參數的構造函數,即使它什么也不寫也可以,具體原因請參見:https://www.cnblogs.com/HotPants/p/11421065.html