C 刪除不完全型別陣列

2021-07-10 13:14:49 字數 1321 閱讀 1975

看智慧型指標的時候遇到一組函式蠻有意思的,即checked_delete(t* x)和checked_array_delete(t* x),這兩個函式的作用是安全刪除引數所指向的變數或陣列。

templateinline void checked_delete(t* x)

templateinline void checked_array_delete(t* x)

函式只有最後一行不同,分別呼叫了delete和delete操作符,順便說一句,在c/c++中指標既可以指向乙個變數,也可以指向乙個陣列,因此這兩個函式僅僅從引數無法區別出來待刪除的是單個變數還是陣列,只能由呼叫者自行保證呼叫了正確的函式。

函式總共三行語句,第三行是根本目的,很容易理解,前兩行的目的就是為了所謂的安全性了。怎麼個安全法呢?這兩個函式是函式模版,在編譯時無法確定引數的型別,而動態執行時的錯誤是比較棘手的,所以用這行**:

typedef char type_must_be_complete[ sizeof(t)? 1: -1 ];

來將執行時錯誤轉變為編譯期錯誤。這句話其實就是定義了乙個固定大小的char型陣列,陣列名為type_must_be_complete,陣列大小是多少呢?是sizeof(t)?1:-1, ?:這個三元操作符大家都很熟悉了,若sizeof(t)非0,這個表示式的值為1,即typedef了乙個大小為1的char型陣列,否則定義乙個大小為-1的陣列。陣列大小還能為負數?當然不能,於是就會報錯,而且是編譯期錯誤,於是就將乙個動態執行時錯誤在編譯時就發現了。

接下來解釋sizeof什麼時候返回0. c/c++語言本身似乎沒有這種情況,但有些編譯器會作一些擴充套件,比如gcc對於incomplete type使用sizeof時,會返回0.那什麼又叫做incomplete type呢,就是那些宣告了,但沒有定義的型別,例如:

class a;

extern a a;

c++標準允許通過乙個 delete 表示式刪除指向不完全類的指標。如果該類有乙個非平凡的析構函式,或者有乙個類相關的 delete 操作符,那麼其行為就是無定義的。因此編譯器作了這種擴充套件,以將這種未定義的行為轉為編譯期錯誤,幫助程式設計師們及早發現。

函式的第二行語句的作用據說是為了防止編譯器優化,因為編譯器檢測到typedef的型別未被使用到的話可能就會將其優化掉,因而第二行語句使用了這個型別,告訴編譯器這個typedef是有用的,不能優化掉。至於(void)強制型別轉換,問了同學,說是為了消除編譯器對未使用sizeof返回值的警告。

僅僅幾行**都有這麼多講究,要學的東西還很多啊。錯誤和疏漏的地方歡迎批評指正!

不完全型別

c 允許在乙個 檔案中存放多個類,但這樣往往不便於類的管理,所以一向是提倡乙個檔案中只存放乙個類。不過呢,隨著類規模的不斷膨脹,乙個檔案中存放乙個類也有些顯得臃腫,或者是在某個角度上不便於 的組織。因此,c 2.0中引入了不完全型別的概念,即啟用了新的修飾符partial。借助該修飾符,我們可以在多...

不完全型別

不完全型別指 函式之外 型別的大小不能被確定的型別 總結一下,c的型別分為 結構體的宣告就是乙個不完全型別的典型例子。struct woman tag struct man tag struct woman tag 這樣是沒問題的。如果將man tag結構中的struct woman tag wif...

不完全型別

有時候我們在一些編譯器寫 的時候會碰見不完全型別這個編譯錯誤,那麼什麼是不完全型別,為啥會出現呢 不完全型別指 函式之外 型別的大小不能被確定的型別 只能以有限方式使用。不能定義該型別的物件。不完全型別只能用於定義指向該型別的指標及引用 1 或者用於宣告使用該型別作為形參型別或者返回值型別。c的型別...