在开发中,经常会用到一些数组,它里面存放一定数量(已知,不是太多)的特定元素。在使用数字表示的数组下标访问数组中元素的时候,根本不知道该元素是否是需要的那个元素,而且使代码可读性降低,甚至还会出现下标越界的危险。
比如,现在有如下的继承体系:
class CShape;
class CSquare : public CShape;
class CRectangle : public CShape;
class CCircle : public CShape;
class CEllipse : public CShape;
现在需要一个数组来存放每种形状的对象的指针。最简单的就是使用下面的代码定义数组并给数组元素赋值:
CShape* arrShape[4];
arrShape[0] = new CSquare();
arrShape[1] = new CRectangle();
arrShape[2] = new CCircle();
arrShape[3] = new CEllipse();
这样的代码当然没有什么问题。
可是每次要得到一个长方形的对象指针的时候,都要用 arrShape[1]来访问。这样的代码可读性非常差:如果不看前面的数组赋值代码,根本不可能知道 arrShape[1]里面存放的是什么。
而且,一不小心就会写错数组下标而导致下标越界的错误。C++ 在编译阶段是不检查下标越界的,所以下标越界的错误只会在运行时被暴露出来。如果出现错误的代码跟定义数组和给数组元素赋值的代码相隔较远的话,查找起来也比较麻烦。
另外,这段代码的扩展性也很差:如果在这个继承体系中加入了三角形,那么数组定义和给数组元素赋值的代码都要修改。
有什么好方法避免上面所说到的种种缺点吗?当然有,那就是用枚举定义有意义的数组下标。
针对上面的例子,可以定义出如下的一个枚举类型:
enum ShapeIndex
{
eSqure,
eRectangle,
eCircle,
eEllipse,
eShapeCount
};
数组定义和赋值使用下面的代码:
CShape* arrShape[eShapeCount];
arrShape[eSquare] = new CSquare();
arrShape[eRectangle] = new CRectangle();
arrShape[eCircle] = new CCircle();
arrShape[eEllipse] = new CEllipse();
这样每次要得到一个椭圆的对象指针的时候,可以使用 arrShape[eEllipse]来访问。通过 eEllipse 这个有意义的数组下标,该数组元素指针所指的对象一目了然。
如果对数组的访问都使用这种方法,就可以有效的避免数组下标越界的错误。
另外,这种方法使数组有很好的可扩展性。如果在这个继承体系中加入了其他子类,只要在枚举中 eShapeCount 前面加上相应的项即可,数组定义的代码根本不用修改(当然不能忘了添加数组元素赋值的代码)。