【C++】過載二維陣列下標 [ ][ ]
阿新 • • 發佈:2019-02-12
寫在文章開頭的話
讀完這篇文章後,你將學習到下面的知識:
(1)一個多維陣列是如何工作的
(2)如何過載二維陣列下標
1. 分析
過載一維陣列下標很簡單,通過下標傳入的索引值,返回內部陣列中相應的值。那過載二維陣列的下標運算呢?
其實過載二維和一維本質是一樣的,因為 C/C++ 中所謂的 “二維或多維陣列”都是由簡單的一維陣列表示的。舉個例子哈:
下面是兩個 int 陣列,第(1)個是熟悉的一維陣列,第(2)個是熟悉的二維陣列,現在你要做的就是將第(2)個數組看成是一個一維陣列。
(1)int array[3];
(2)int array[3][4];
怎麼看?可以在頭腦中將第(2)個數組陣列看成如下定義的方式, 陣列 array 包含 3 個元素,其中每個元素又都是一個數組型別(或者說是一個指標型別)。
typedef int T[4];
T array[3];
至於更高維數的陣列,也是這樣看,比如如下的三維陣列,可以採用下面的方式來定義。
我在網上也看到過一些別人的實現方法,其中在 文章(http://edu.gamfe.com/tutor/d/24416.html)中就提到了一種過載方法,使用一維陣列來表示二維陣列,這是大多數的實現方法,但是其實現過程過於複雜,其構建了兩個類,分別用來獲取行和列,然後計算出指定的二維下標對應的內部一維陣列的值並返回。
對於固定維數的二維陣列下標過載,一般在像3D圖形方面經常涉及到一些平移轉換矩陣時用到,這裡以 4 * 4 的矩陣為例,實現程式碼如下:
測試賦值和取值操作,均正常:
3. 過載維數可變的二維陣列下標
對於可變的二維陣列下標過載,在陣列初始化時指定維數,之後可以像一般的二維陣列進行賦值和取值操作,採用模板實現,程式碼如下:
讀完這篇文章後,你將學習到下面的知識:
(1)一個多維陣列是如何工作的
(2)如何過載二維陣列下標
1. 分析
過載一維陣列下標很簡單,通過下標傳入的索引值,返回內部陣列中相應的值。那過載二維陣列的下標運算呢?
其實過載二維和一維本質是一樣的,因為 C/C++ 中所謂的 “二維或多維陣列”都是由簡單的一維陣列表示的。舉個例子哈:
下面是兩個 int 陣列,第(1)個是熟悉的一維陣列,第(2)個是熟悉的二維陣列,現在你要做的就是將第(2)個數組看成是一個一維陣列。
(1)int array[3];
(2)int array[3][4];
怎麼看?可以在頭腦中將第(2)個數組陣列看成如下定義的方式, 陣列 array 包含 3 個元素,其中每個元素又都是一個數組型別(或者說是一個指標型別)。
typedef int T[4];
T array[3];
至於更高維數的陣列,也是這樣看,比如如下的三維陣列,可以採用下面的方式來定義。
由於實際中二維陣列用的較多,所以,下面主要是練習二維陣列的下標過載。那過載二維陣列的下標有什麼好處呢?最大的好處就在於可以使程式碼簡潔直觀。int array[3][4][5]; typedef int T1[5]; typedef T1 T2[4]; T2 array[3];
我在網上也看到過一些別人的實現方法,其中在 文章(http://edu.gamfe.com/tutor/d/24416.html)中就提到了一種過載方法,使用一維陣列來表示二維陣列,這是大多數的實現方法,但是其實現過程過於複雜,其構建了兩個類,分別用來獲取行和列,然後計算出指定的二維下標對應的內部一維陣列的值並返回。
下面介紹我自己寫過載二維下標實現方式,不一定最好,但比上面提到的方式要好。
2. 過載固定維數的二維陣列下標對於固定維數的二維陣列下標過載,一般在像3D圖形方面經常涉及到一些平移轉換矩陣時用到,這裡以 4 * 4 的矩陣為例,實現程式碼如下:
struct Matrix4f { float m[4][4]; float * const operator[](const int i) { return m[i]; } };
測試賦值和取值操作,均正常:
Matrix4f m;
m[0][0] = 1.0f;
m[1][1] = 9.9f;
cout << m[0][0] << endl; // 1
cout << m[1][1] << endl; // 9.9
3. 過載維數可變的二維陣列下標
對於可變的二維陣列下標過載,在陣列初始化時指定維數,之後可以像一般的二維陣列進行賦值和取值操作,採用模板實現,程式碼如下:
template <typename T> class Matrix { public: Matrix(int row, int col) :m_row(row), m_col(col), m_data(nullptr) { m_data = new T[m_row * m_col]; } ~Matrix() { if (m_data != nullptr) { delete[] m_data; m_data = nullptr; } } // 返回二維陣列的第 k 行地址 T * operator[](int k) { return &m_data[k * m_col]; } private: int m_row; int m_col; T *m_data; };
測試賦值和取值操作:
Matrix<int> m2(3, 4);
m2[0][0] = 2;
m2[2][3] = 9;
cout << m2[0][0] << endl; // 2
cout << m2[2][3] << endl; // 9
和一般的二維陣列一樣沒有越界檢查,所以越界操作也是可以的,但是儘量使用前檢查索引是否越界,以免引發未知錯誤。
轉載請註明出處:http://blog.csdn.net/xiaohui_hubei/article/details/21334141