物件陣列的構造:
物件資料的構造一般有兩種方式:靜態和動態
(1)靜態分配
以string類為例,string a[10];就是以靜態形式構造資料,這樣的陣列的個數是確定的不能修改的。
像這樣的陣列怎麼進行構造和析構呢?
編譯器在構造陣列的時候會生成乙個使用預設建構函式的陣列建構函式arr_new(char *p,sizeof(string),int num,建構函式位址,析構函式位址);同樣也會生成陣列析構函式,形式類似。arr_del(char *p,sizeof(string),int num,析構函式位址);
若陣列構造中間出現異常,該函式必須保證已構造的物件析構,然後釋放記憶體。
如果陣列物件不使用預設建構函式構造物件,必須顯示構造,否則,未顯示構造的物件將會使用上述函式進行預設構造。
(2)動態分配
使用new表示式進行操作,string *a=new string[10];
new表示式分為兩個步驟:首先通過記憶體分配所用型別大小的空間,然後再該空間上呼叫相應的建構函式進行構造,上述語句使用預設建構函式。
delete 表示式則釋放指標所指的記憶體(首先析構),大小按照指標型別的大小計算。與陣列相對應的為delete a;
這樣就可能造成一定錯誤:
當使用基類指標指向乙個子類陣列,則釋放的時候將可能會產生錯誤
base *p=new derived[10];
delete p;
我們知道,new出來的陣列是根據derived物件大小*10的記憶體空間,而delete 則是根據指標型別的大小進行析構和釋放記憶體的,且使用類似與靜態分配時的arr_del函式進行析構釋放記憶體,這樣呼叫的就會是基類的析構函式和基類物件的大小。除了第乙個元素,其他元素的析構都會錯誤的進行。
因此建議:不要使用基類指標指向乙個子類陣列。
上訴問題根據編譯器而不同,微軟的編譯器可以支援使用基類指標釋放子類陣列,但是基於cfront的編譯器g++將會出現錯誤,它會將指標型別的大小和析構函式傳入它生成的arr_del函式進行析構釋放,導致記憶體錯誤。
深入探索C 物件模型
深入探索c 物件模型 本書目錄結構如下 第1章 關於物件 object lessons 加上封裝後的布局成本 layout costs for adding encapsulation 1.1 c 模式模式 the c object model 簡單物件模型 a object model 驅動物件模...
深入探索C 物件模型之物件
物件 一 在c語言中,資料 和 對資料的處理 函式 分開宣告的,也就是說,語言本身並沒有支援 資料和函式 之間的關聯性。例如,typedef struct point3dpoint3d 而在c 中,座標型別和座標數目都可以引數化 template class point type operator ...
深度探索c 物件模型 6
class foo 我是用的編譯器vs2015會報這樣的錯誤無法過載僅含返回型別不同的函式 當僅需讀 val時,呼叫const int val 當需要更改 val時,呼叫int val 而現在由於c 不支援這種情況,那麼我們只能採取折衷的方案,第一種方法是,在讀寫的地方都使用int val 對於僅需...