關於為什麼自訂的 class 沒有寫 destructor 他的 array size 就沒有被存起來的原因,
有匿名高手來信指教,跟大家一起分享一下。
============================================================================
標題: Re: [情報] 1111 上課內容更正
時間: Mon Nov 23 02:13:04 2009
老師您好!
關於您提到為什麼只有「有 define destructor 的 user defined
class」才會將 array size 記錄在前面,我有以下看法。
我覺得可以從「為什麼編譯器要這麼作」的觀點去想。如果是在 C
語言的時候,我們要 free 一個陣列,我們不用多做什麼事情,只要
告訴 OS:這塊 memory 我不要了,OS 自動會從 heap 回收它。不過
在 C++ 中,情況變得不一樣,我們必需確保 destructor 會被喚起。
然而,然我們的陣列長度不是固定的時候,如何知道有多少個 object
將要被 destruct 呢?我們只知道第一個 object 的位址呀!
當然,在 static storage 或者 automatic storage 之中,這是一
件很容易的事,static storage 與 automatic storage 之中,陣列的
大小是固定的。(即便 automatic storage 的大小不是固定的,也可以
透過計算 stack top (eg. esp) 與陣列的 address 得知他的個數) 然
而對於 new 出來的 array,事情卻不是這麼容易。
在很久很久以前,聽說 C++ front 的某一版是要求程序員傳入陣列
的大小,如 delete [5] array。不過後來,大家認為沒有理由要求程
序員記住陣列的大小,所以把這個值拔掉,要大家寫 delete [] array
就好了。那誰來記 array 的大小呢?
聽說有二個解法,第一個是在 array 的前面加上 cookies (也就是
G++ 使用的方法;第二個是在 C++ standard library 用一種資料結
構記錄 address 與對應的 array size。
如果從這個關點來考量,我們就不難理解為什麼只有有 destructor
的 class 才會有這個 cookies 了!因為沒有 destructor,我們就不
需 destruct 陣列之中的每一個元素了,當然也不需要準備 cookies。
另外,IMHO,我覺得 user-defined class with destructor 這句話
也不是那麼精確。eg.
class A { ~A() {} };
class B : public A {};
B * b = new B[5];
cout << *(reinterpret_cast<size_t *>(b) - 1) << endl;
delete [] b;
應該要改成「user-defined class with destructor or destructor
automatically composited by compiler」可能會比較精準。(當然這
叫做雞蛋挑骨頭 XD )
※ 引述《ric2k1 (Ric)》之銘言:
: 昨天上課時有兩個地方講錯了!
: 下課有人來詢問/指正,但是我後來忘記 PO 了...
: 不過前幾篇已經有同學提出,所以在這裡統一說明一下:
: 2. 如果自訂的 class 沒有 define destructor,並不是 new / delete operator
: overloading 失去作用,我口誤了...
: 而是 array 的 size 不會被存在前面一個 size_t 的地方.
: 另外,請注意只有 "user-defined class with destructor" 而且用 "new" 來
: create array object 時,compiler 才會偷偷的將 size 存在之前的 size_t 裏.
: 以下的狀況並不會有 size 被存起來:
: - int *a = new int[10]; // predefined types
: - A a[10]; // static array; no matter it's A or int
※ 編輯: ric2k1 來自: 140.112.21.241 (11/26 17:48)
1F:推 dryman:強! 11/26 18:42
2F:推 hrs113355:推 11/26 19:47