1. 程式人生 > >用列舉型別作為陣列下標

用列舉型別作為陣列下標

  在開發中,經常會用到一些陣列,它裡面存放一定數量(已知,不是太多)的特定元素。在使用數字表示的陣列下標訪問陣列中元素的時候,根本不知道該元素是否是需要的那個元素,而且使程式碼可讀性降低,甚至還會出現下標越界的危險。
    比如,現在有如下的繼承體系:
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前面加上相應的項即可,陣列定義的程式碼根本不用修改(當然不能忘了新增陣列元素賦值的程式碼)。