1. 程式人生 > >讀《More Effective C++35個改善程式設計與設計的有效方法》之條款3:絕對不要以多型方式處理陣列

讀《More Effective C++35個改善程式設計與設計的有效方法》之條款3:絕對不要以多型方式處理陣列

有以下程式:

<pre name="code" class="cpp">class Base
{
public:
	Base(int n = 0) : _b(n) {}
	int _b;
};

class Devide : public Base
{
public:
	Devide(int n = 0, int m = 0) : Base(n), _d(m) {}
	int _d;
	int _d1;
};

void print(std::ostream& s, const Base array[], int num)
{
	for (int i = 0; i < num; ++i)
		s << array[i]._b << std::endl;
}


在主函式中這麼呼叫:
	Base b1[10];
	print(std::cout, b1, 10);
執行結果如下:

結果是正確的,但是如果我以如下方式執行:

	Devide d[10];
	print(std::cout, d, 10);
會發生什麼呢?


結果有些卻是不對的。更確切的說,是未定義呢。

為什麼呢。

因為我們都知道陣列array[i]是一個指標算術表示式,它的地址是*(array+i),array是指標,指向陣列起始處,所以array+i,所指的記憶體,就應該是array+i*sizeof(物件),那麼這邊的物件是什麼呢,我們宣告的是Base物件,即使我們傳過來的是Devide的物件,所以,array+i的地址就是array+i*sizeof(Base),但是其實它的大小是Devide的大小,所以很明顯,除了第一個,後面的地址,都是錯誤的。如果我把Devide的成員函式的值賦值一下,結果就不一樣了。

所以,絕對不能以多型的方式來處理陣列,否則會讓你“大吃一驚的”。