1. 程式人生 > >C++語言99個常見程式設計錯誤 常見錯誤89:持有class物件的陣列

C++語言99個常見程式設計錯誤 常見錯誤89:持有class物件的陣列

常見錯誤89:持有class物件的陣列
  當心持有class物件的陣列,尤其是持有基類物件的陣列。
  陣列的索引操作只是指標算術的縮寫,因此array[i]等價於*(array+i)。不幸的是,編譯器
會基於“array指標指向有B物件的陣列”的前提做指標的加法運算。如果派生物件具有更大的
尺寸,或迥異的記憶體佈局,那麼索引操作將取得錯誤的地址。
  用於訪問持有基類物件的陣列指標運算通常不能用於訪問持有派生類物件的陣列。
  持有基類物件的陣列一般而言是不提倡使用的,而持有class物件的陣列都得受到嚴密監視。
  較佳的做法是讓陣列持有指向class物件的指標,而非class物件本身,這麼一來,就可以在陣列上進行多型
應用,而不會引發指標算術相關的錯誤。

  更佳的做法是徹底捨棄裸陣列,而使用某種標準庫中的容器元件,一般選用vector元件。

apply.cpp
#include <iostream>

struct B {
	B() { a = 1; b = 2; }
	int a, b;
};

void apply( B array[], int length, void (*f)( B & ) ) {
    for( int i = 0; i < length; ++i )
        f( array[i] );
}

void somefunc( B &b ) {
	std::cout << "B::a = " << b.a << " , B::b = " << b.b << std::endl;
}

struct D : public B {
	D() { c = 3; d = 4; }
	int c, d;
};

int main() {
	D *dp = new D[3];
	apply( dp, 3, somefunc ); // 災難爆發
	getchar();
	return 0;
}

輸出
B::a = 1 , B::b = 2
B::a = 3 , B::b = 4
B::a = 1 , B::b = 2