C 11特性 《深入理解C 11 讀書筆記

2021-07-22 23:17:22 字數 3999 閱讀 9573

新增關鍵字

struct alignas(32) colorvector

//沒有alignas關鍵字的話,對齊到8位,加上的話,對齊到32位,能提公升效率。

對齊的資料在讀寫上會有效能上的優勢。比如頻繁使用的資料如果與處理器的快取記憶體器大小對齊,有可能提高快取的效能。而資料不對齊可能造成一些不良的後果,比較嚴重的當屬應用程式退出。典型的,如在有的平台,硬體將無法讀取不按位元組對齊的某些型別資料,硬體會丟擲異常來終止程式。
- alignof

表示乙個定義完整的自定義型別或者內建型別或者變數,返回的值是乙個std::size_t型別的整型常量。
alignof(int);//值是4,表示對齊的位數
推導型別,比較典型的是跟typedef和using的合用。在一些常量,基本型別,運算子,操作符等都已經被定義好的情況下,型別可以按照規則被匯出。而用using,就可以為這些型別取名。

using nullptr_t = decltype(nullptr); 

vector

vec;

typedef

decltype(vec.begin()) vectype;

for (vectype i = vec.begin() ; i < vec.end(); i++)

auto z;

z = 1; //編譯報錯 應該是auto z = 1;

用auto的優勢在於擁有初始化表示式的複雜型別變數宣告時簡化**。還可以免除程式設計師在一些型別宣告時的麻煩或避免一些在型別宣告時的錯誤,另乙個優勢在於其「自適應」效能在一定程度上支援泛型程式設計。
template

double sum(t1 &t1, t2 &t2)

但auto不是萬能的,以下幾種情況不能編譯

void fun(auto x = 1) {} //auto函式引數,無法通過編譯

struct str

int main(); //auto模板引數(例項化時),無法通過編譯

}

template

int bit_copy(t &a, u&b)

int main()

struct a

a(double d, int i){}

a(float f, int i, const

char* c){}

}struct b : a

除了繼承建構函式外,c++11還引進了委託建構函式。

class

info

info

(int

i) : info

() //委託建構函式

info

(char

e): info

() }

void except_func() noexcept;
另一種是可以接受乙個常量表示式作為引數,常量表示式會轉換成乙個bool型別的值,為true則函式不會拋異常,反之則有可能會拋異常。

void except_func()

noexcept(常量表示式);

它更大的作用是用來保證執行緒安全,如析構函式宣告成noexcept。

void

operator

delete(void *) noexcept;

char *cp = nullptr;//可以隱式轉換成char *

//以下**不能通過編譯

//不可以轉換成整型,而任何型別也不能轉換成nullptr_t

int n1 = nullptr;

int n2 = reinterpret_cast

(nullptr);

constexpr

int getconst()

int arr[getconst()] = ;//這種可以通過編譯,如果沒有constexpr,則不能通過編譯。

在函式返回型別前加入關鍵字constexpr來使其成為常量表示式函式。常量表示式函式比較嚴格,要滿足下面幾條要求:

- [ ] 函式體只有單一的return語句

- [ ] 函式必須返回值

- [ ] 在使用前必須已有定義

- [ ] return返回語句表示式中不能使用非常量表示式函式,全域性資料,且必須是乙個常量表示式。

const i = 1;

constexpr

int j = 1;

上面兩條語句的區別在於:如果i在全域性名字空間中,編譯器一定會為i產生資料,而對於j,如果不是有**顯示地使用它的位址,編譯器可以不為它生資料,只做為編譯時期的值。

- thread_local

現有的說明

const

char * hello() //返回hello(函式名)

long

long

int lli = -9000000000ll;

#if __cplusplus < 201103l

#error "should be use c++11 implementation"

#endif

這裡使用了#error,不支援c++11的話,編譯器就報錯了。

原有的優化

class

init

c++11則放開這個限制,但對於非常量的靜態成員來說,c++11跟c98保持一致。

- sizeof

在c98裡,對非靜態成員變數使用sizeof是不能夠通過編譯的。但c++11裡可以。

struct people

sizeof(people::handle)是會法的

extern

template

void fun(int);

template

class x{}

template

class y{}

y1> > x1; //c98裡能通過

y2>> x2; //c98不能通過編譯,但c++11可以

enum

class

type ;

相關的用法

lambda函式的語法定義如下:

[capture][parameters] mutable->return-type其中:

- [ ] capture:捕捉列表。是lambda的引出符,根據此來判斷這個**是不是lambda的函式。捕捉列表能夠捕捉上下文的變數以供lambda函式使用。

- [ ] parameters:引數列表。如果沒有引數可以跟()一塊省略

- [ ] mutable: mutable修飾符。預設情況下,lambda總是乙個const函式。mutable可以取消其常量性。

- [ ] return-type:返回型別。沒有返回值的時候可以同符號->一塊省略。

- [ ] :函式體

int main()

;//最簡單的lambda函式

int a = 3;

int b = 4;

[=] //省略了引數列表與返回型別,返回型別由編譯器推斷為int

auto fun1 = [&](int c) //省略了返回型別,無返回值

auto fun2 = [=, &b](int c) -> int //各個部分都完整的函式

}

深入理解C 11 筆記

include using namespace std classa a 對於含有堆記憶體的類,需要提供深拷貝的拷貝建構函式,避免預設的拷貝構造使用淺拷貝導致堆記憶體的重複刪除。a const a a m ptr new int a.m ptr 通過移動構造,a 作為函式引數,只使用淺拷貝避免臨時物...

深入理解C 11(九)

move語義 我們知道移動語義是通過右值引用來匹配臨時值的,那麼,普通的左值是否也能借助移動語義來優化效能呢,那該怎麼做呢?事實上c 11為了解決這個問題,提供了std move方法來將左值轉換為右值,從而方便應用移動語義。move是將物件的狀態或者所有權從乙個物件轉移到另乙個物件,只是轉移,沒有記...

深入理解C 11(十二)

改進物件池模式 物件池對於建立開銷比較大的物件來說很有意義,為了避免重複建立開銷比較大的物件,可以通過物件池來優化。物件池的思路比較簡單,事先建立好一批物件,放到乙個集合中,每當程式需要新的物件時,就從物件池中獲取,程式用完該物件後都會把該物件歸還給物件池。這樣會避免重複建立物件,提高程式效能。物件...