物件的構造和析構
講解在以下幾種情況下
編譯器是如何安插構造和析構函式?
1.全域性物件
2.區域性靜態物件
3.陣列物件
1)全域性物件
matrix g_identity;
main()
c++保證了在main函式中第一次用到g_str之前,將g_str構造出來,在main()函式結束之前將g_str毀掉。
乙個global class只能夠被乙個常量表示式(編譯期間求其值得那種)。非class全域性變數在編譯期間可以放置在data segment並且指定特定的值(如int g_tmp),但是如果是class全域性變數,可以放置在data segment並且制定為0,但是建構函式一定要到程式執行時才會實施。
針對class全域性變數採用munch策略:
1. 為每乙個需要靜態初始化的檔案產生乙個_sti函式。如之前的g_identity,會在matrix中產生_sti函式(static initialization)
_sti_matrix_c_identity()
2.類似會產生乙個_std函式,針對每個靜態初始化物件條用destructor
3.提供一組runtime library「munch」函式:乙個_main()函式(用以呼叫可執行檔案中的所有_sti()函式),以及乙個exit()函式(所有_std()函式)
int main()
如何收集各個object file中的_sti()函式和std()函式呢?
nm命令(
列出乙個目標檔案中的各種符號),將符號表的資訊匯入到munch程式,然後通過munch根據符號表的名稱,搜尋_sti和_std開頭的名稱,將這些函式名稱加入到乙個jump table中,接下來將這個**寫入到program text檔案中,然後cc命令重新**,將這個內含jump table的檔案加以編譯,整個可執行檔案然後被重新鏈結。
2)區域性靜態物件
const matrix& identity()
區域性靜態物件必須只能夠構造和析構一次,採用方法匯入乙個臨時性物件用以保護m的初始化操作,第一處理identity函式,這個臨時物件為false,呼叫過之後設定回true,destructor類似。
3)陣列物件
point knots[10];
需要配置記憶體來存10個連續的poingt元素,同時呼叫default建構函式,輪流施於每個元素之上。
void* vec_new
針對編譯器很可能轉換為
vec_new(&knots, sizeof(point), 10, &point::point, 0);
釋放的時候也會有類似的vec_delete.
void* vec_delete
深入c 物件模型之執行期語意學
1.物件的構造與解構 一般而言,constructor 和 destructor的安插都會如你所預期 c 偽碼 point point 一般而言會被安插在這裡 一般而言會被安插在這裡 注意 一般而言我們會將物件放置在使用它的程式附近,這樣做可以節省不必要的物件產生操作和摧毀操作。1 全域性物件 c ...
深入探索C 物件模型 之 執行期語意學
在 c 中的一件很困難的事,就是不太容易從程式 看出表示式的複雜度。如下面語句 if yy.operator xx.getvalue 將被擴充套件為下面這樣的 c 偽碼 物件的構造和解構 建構函式一般在物件被構造後呼叫,而析構函式必須被放在每乙個離開點 當時 object 還存活 隻前呼叫。一般而言...
深入探索C 物件模型之六 執行期語意學
c 最困難的一點就在於 無法從程式原始碼看出程式表示式的複雜度。因為編譯器會在背後給你做很多的工作。對於一些表示式諸如t a b c,編譯器可能會建立在執行期過程建立臨時物件,那麼在程式的出口處編譯器就需要安插必要的 來保證建立的臨時物件都得到有效的析構。如果遇到goto switch等會產生多個邏...