1. 程式人生 > >【C++】過載二維陣列下標 [ ][ ]

【C++】過載二維陣列下標 [ ][ ]

寫在文章開頭的話
讀完這篇文章後,你將學習到下面的知識:
(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