【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];
由于实际中⼆维数组⽤的较多,所以,下⾯主要是练习⼆维数组的下标重载。那重载⼆维数组的下标有什么好处呢?最⼤的好处就在于可以使代码简洁直观。
我在⽹上也看到过⼀些别⼈的实现⽅法,其中在 ⽂章( )中就提到了⼀种重载⽅法,使⽤⼀维数组来表⽰⼆维数组,这是⼤多数的实现⽅法,但是其实现过程过于复杂,其构建了两个类,分别⽤来获取⾏和列,然后计算出指定的⼆维下标对应的内部⼀维数组的值并返回。
下⾯介绍我⾃⼰写重载⼆维下标实现⽅式,不⼀定最好,但⽐上⾯提到的⽅式要好。
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
和⼀般的⼆维数组⼀样没有越界检查,所以越界操作也是可以的,但是尽量使⽤前检查索引是否越界,以免引发未知错误。