C 11學習筆記 Type Support

2021-06-26 20:55:26 字數 2824 閱讀 2760

其實主要還是對c++的std庫的學習吧,雖然用的不少但是對c++的全貌還不太了解。

主要包括3個部分:基本型別、rtti、萃取技術(traits)。

size_t

用的太多了,不說了。

ptrdiff_t

乙個有符號的型別,通常用來表示兩個指標相減的結果,是乙個機器相關的型別。

和size_t不同的是,size_t是乙個無符號的整形變數,通常用來表示長度,而ptrdiff_t是個帶符號的變數,可能是個負數。

nullptr_t

這玩意是為了防止c++過載的時候語義混淆用的,就相當於空指標,g++ 4.4.3的編譯器不支援,暫時不管了。

max_align_t

機器相關的型別,結構體對齊的最大對齊的位元組數。

offsetof

用於計算結構體內定義的變數到結構體首位元組的偏移位元組數,這玩意是從也就是標準c庫里延伸出來的。比如

struct a
offsetof(a, a)計算出來就是0,同樣的soffsetof(a, b)算出來是4,c是8.。

同樣可以用來計算class的偏移量,但是如果class裡面定義了函式,那麼編譯的時候會給警告(目前還沒發現影響實際結果的情況)。

如果定義了虛函式,那麼會在偏移位址前面加上個虛函式表的4個位元組,編譯的時候也會有警告。

template

<>

class

numeric_limits

<

int(bool,unsigned...)

>

一些跟機器相關的型別限制,可以用來處理資料溢位時的一些情況(上溢、下溢),

一系列的特化模板,特化的型別基本包括所有的基本型別,比如如果int型的變數需要對上溢進行處理,那麼

int i;

if (i == std::numric_limit::max())

else

該模板還包括一些其它的型別特化函式。習慣了裡的數值上下限巨集,乍一看這個特化模板好像沒太大意義,但是它的意義在於統一的介面,很方便**的精簡和書寫。尤其是用到自定義的型別的時候,特化std::numric_limit::max()這樣就能返回自定義型別t的最大值。

特化方法:

namespace std 

};}

執行時刻檢查,dynamic_cast之類都屬於這裡,因為編譯器作了比較多的額外處理,因此rtti一般來說是比較消耗資源的。

type_info和typeid

type_info是個類,禁用了拷貝構造和建構函式、「=」運算……有點類似單例模式,因此只能通過typeid去獲得。

typeid是個關鍵字,返回的是個type_info的const reference以供使用。

typeid獲取的type_info不具有多型性,如果typeid乙個基型別的指標(實際指向的是乙個派生類),那麼返回的type_info的name()則是基類的乙個指標名稱而不是派生類。

不同的編譯器對type_info的name的實現不一樣,g++ 4.4.3對自定義型別的返回值是(型別名稱的字串長度)+型別名,比如我定義了乙個類test,那麼返回的是4test,如果typeid的是乙個指標,那麼在最前面加乙個p,p4test。

type_index

bad_typeid(異常)

如果定義了乙個指向多型類的指標,而又對將該指標置0,此時對該指標物件使用typeid()則會丟擲該異常。

bad_cast(異常)

dynamic_cast引用時丟擲的異常,cast.引用時會丟擲該異常,比如b&b = dynamic_cast(a);不管a和b之間有沒有派生關係,都會丟擲異常。

c++萃取技術,具體實現這裡暫時不深究,網上有很多資料,看起來也比較枯燥,但是這玩意很強大。這裡只是簡單的過一下它提供的介面。

主要的型別判定類別,比如is_enum/is_void/is_class等等,用來判斷一些基本的型別。

顧名思義,復合型別判定。

乙個型別的屬性,比如const、volatile、抽象類、多型類等等。

這裡涉及到幾個概念:

is_trivial:極簡型別,這個還是看文件吧……這裡就不翻譯了,一大堆,包括trivial default construct的定義。

is_pod:平面型別 ("plain old data type"),簡單來說即可以用c語言裡面的malloc直接建立的型別。如果該自定義型別裡有了多型相關等c++的東西,那麼就會返回false。c++11裡對pod型別的概念有詳細的說明。

判斷乙個類是否支援拷貝構造、有沒有虛析構等等……

返回一些型別的對齊要求等,具體還是很清楚。

這個比較神奇,去掉已經定義好的一些型別的某些屬性(改變已經宣告的型別定義,生成新的型別),相當於typedef新的型別。

用於新增、刪除一些const、volatile屬性。

修改引用的屬性。

修改指標的屬性。

使乙個型別是否具有符號型別。

按照我的理解這一組函式介面都是用來將執行期間可能出現的錯誤提前到編譯期間就報告.

比如用enable_if可以提供一種傻瓜式轉換的介面:

template

<

class t>

typename std::

enable_if

<

std::is_floating_point

::value, t>

::type

foo1(t t)

那麼呼叫foo1(5)的時候在編譯的時候就會報錯。

目前就看到乙個型別integral_constant,用來給常量型別賦值。

c 11學習筆記

c 98的 std auto ptr已經被徹底遺棄了,取而代之的是unique ptr shared ptr與weak ptr。大部分時候我們自己手動申請記憶體方式記憶體都是沒有問題的,問題是如果程式很大了之後,乙個複雜的物件,多次拷貝的代價非常高,很多地方都會使用到,只存在乙份拷貝顯然是最好的,這...

C 11學習筆記 五

指標空值 nullptr include using namespace std void f char c void f int i int main 本程式中,null被定義為0,這裡引發錯誤的原因是 c 98中,0既可以是乙個整形,也可以是乙個 void 指標。如果想要呼叫f char c 版...

C 11學習筆記二

用處 基類擁有眾多建構函式而派生類只有一些成員函式 資料不多 時,可以直接繼承基類建構函式而不必重寫。用法 class base class derive base 注意 如果派生類有多個基類時有可能導致衝突,解決辦法是派生類顯示定義該建構函式 用處 一些建構函式需要呼叫相同的 類似的 段時,可將該...