讀《More Effective C++35個改善程式設計與設計的有效方法》之條款3:絕對不要以多型方式處理陣列
阿新 • • 發佈:2019-01-25
有以下程式:
<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的成員函式的值賦值一下,結果就不一樣了。
所以,絕對不能以多型的方式來處理陣列,否則會讓你“大吃一驚的”。