《深度探索C 物件模型》讀書筆記(6)

2021-04-09 10:05:08 字數 2122 閱讀 4280

***物件的構造和解構***

一般而言,我們會把object盡可能放置在使用它的那個程式區段附近,這樣做可以節省不必要的物件產生操作和銷毀操作。

***全域性物件***

全域性物件的靜態初始化策略包括以下幾個步驟:

(1)為每乙個需要靜態初始化的物件產生乙個_sti_...()函式,內含必要的constructor呼叫操作或inline expansions;

(2)為每乙個需要靜態的記憶體釋放操作的物件產生乙個_std_...()函式,內含必要的destructor呼叫操作或inline expansions;

(3)在main()函式的首尾分別新增乙個_main()函式(用以呼叫可執行檔案中的所有_sti()函式)和乙個_exit()函式(用以呼叫可執行檔案中的所有_std()函式)。

建議根本不要用那些需要靜態初始化的全域性物件。 

***區域性靜態物件***

假設我們有以下程式片段:

const

matrix

&identity() 

...

此處的local static class object保證了以下語意:

(a)mat_identity的constructor必須只能施行一次,雖然上述函式可能會被呼叫多次;

(b)mat_identity的destructor必須只能施行一次,雖然上述函式可能會被呼叫多次。

編譯器的實際做法如下:在第一次呼叫identity()時把mat_identity構造出來,而在與相應檔案關聯的靜態記憶體釋放函式中將其解構。(區域性靜態物件的位址在downstream component中將會被轉換到程式內用來放置global object的data segment中)

***物件陣列***

如果你想要在程式中取出乙個constructor的位址,這是不可以的。然而經由乙個指標來啟用constructor,將無法訪問default argument values。那麼,如何支援以下的語句:

complex::complex(

double

=0.0

, double

=0.0);

當程式設計師寫出:

complex c_array[

10];

時,編譯器最終需要呼叫:

vec_new(&c_array,sizeof(complex),10,&complex::complex,0);

為了解決這個問題,可由編譯器產生乙個內部的constructor,沒有引數,在其函式內呼叫由程式設計師提供的constructor,並將default引數值明確地指定過去:

complex::complex()

...

***new和delete運算子***

以constructor來配置乙個class object:

point3d 

*origin 

=new

point3d;

被轉換為:

point3d 

*origin;

if(origin 

=_new(

sizeof

(point3d))) 

...catch

( ... ) 

...}

如果我們配置乙個陣列,內帶10個point3d objects,我們預期point和point3d的constructor被呼叫各10次,每次作用於陣列中的乙個元素:

//完全不是好主意

point 

*ptr 

=new

point3d[

10];

如果我們進行如下的釋放操作:

//只有point::~point被呼叫

delete ptr;

由於其觸發的vec_delete()是通過迭代走過每乙個陣列元素,而本例中被傳遞過去的是point class object的大小而不是point3d class object的大小,整個執行過程將會失敗。

解決之道在於程式層面,而非語言層面:

for(

intix =0

; ix 

<

10; ix++)

...

當然,最好還是避免以乙個base class指標指向乙個derived class objects所組成的陣列。

《深度探索C 物件模型》讀書筆記(6)

物件的構造和解構 一般而言,我們會把object盡可能放置在使用它的那個程式區段附近,這樣做可以節省不必要的物件產生操作和銷毀操作。全域性物件 全域性物件的靜態初始化策略包括以下幾個步驟 1 為每乙個需要靜態初始化的物件產生乙個 sti 函式,內含必要的constructor呼叫操作或inline ...

《深度探索C 物件模型》讀書筆記(5)

純虛函式 在設計抽象基類時,需要注意以下幾點 1 不要將destructor宣告為pure virtual function 如果將destructor宣告為pure virtual function,則設計者一定得定義它。因為每乙個derived class destructor會被編譯器加以擴充...

讀書筆記 《深度探索c 物件模型》 (3)

第四章 function語意學 4.2 虛擬成員函式 a 單一繼承下的virtual function 乙個class只會有乙個virtual table 這個class自己定義的virtual function,它override了乙個可能存在的base class virtual functio...