1. 程式人生 > >C++進階之一

C++進階之一

C++ lamnda


在實際工作中,發現大學C++教科書上的C++知識還不夠用,或者理解不夠深,為此這方面還得沖沖電。下面是簡單整理了以前不太熟悉的幾個點

1. 構造和拷貝函數

l 賦值構造函數:T(T &)

l 賦值拷貝函數: operator = (T &)

l 移動構造函數: T(T &&)

l 移動拷貝函數:operator =(T&&)

一般如果類中有指針成員,建議 disable 掉賦值構造和賦值拷貝函數。而通常出於對性能優化的目的,可以使用移動構造函數和移動拷貝函數來減少冗余拷貝。

舉例說明:

class T {

T(int);

T(const T&);

Operator = (const T&);

T(const T&&);

}

int main() {

T a = T(1);

T && b = T(2);

}

上面T a 的初始化過程中,有一次構造一次拷貝;而T b就只有一次構造了。

2. virtual

l 限定虛函數:virtual func(….) ;

l 限定純虛函數: virtual func(….) =0 , 抽象類只有純虛函數

l 限定被繼承的基類,用作虛基類,避免子類擁有基類中重復的成員方法;

例如: class B: virtual A;

class C: virtual A;

class D: class B, class C; // 那麽D的對象中只有A的一份成員;

l 抽象類的析構函數一定是虛函數(個人的理解是對於裏面的虛函數可能用到的資源是不定的)

3. C++ 11 中的自動推斷變量類型auto 的使用

Auto 的使用極大地方便了枚舉器的使用,隱藏了枚舉的過程,舉例如下:

Auto x1=3.1415169;

Std::map<float, int> mymap;

For (auto it = mymap.begin; it != mymap.end(); it++) {

……

}

4. C++ 匿名函數 lamnda 的使用

本質就是去類臨時函數定義時的名稱,通過【】代替。這種函數通常在一些算法庫中的比較函數、判斷是否相等的臨時函數的定義中。

格式如下:

  [capture](parameters)->return-type{body}

其中capture高速這個臨時函數,是否以及如何使用外部的變量,規則如下:

[] //未定義變量.試圖在Lambda內使用任何外部變量都是錯誤的.

[x, &y] //x 按值捕獲, y 按引用捕獲.

[&] //用到的任何外部變量都隱式按引用捕獲

[=] //用到的任何外部變量都隱式按值捕獲

[&, x] //x顯式地按值捕獲. 其它變量按引用捕獲

[=, &z] //z按引用捕獲. 其它變量按值捕獲

實例如下:

【】(int a, int b->int (int z= a+b; return z);

5. 構造函數和析構函數執行的順序

具體規則如下:

l 如果對象的類型是global/static 等落在.data或者.bss段,那麽對於global的變量,先於main()函數執行構造;對於function domain的則在執行到的地方開始執行構造。析構函數按鏡像對稱的順序進行;

l 如果對象的類型是在棧上,在執行到代碼的地方開始構造,在作用域結束的地方析構;

l 如果對象的類型在堆上,根據顯式調用析構函數的順序執行;如果沒有顯式調用析構,在堆被系統釋放的時候調用析構函數;

l 對於多重繼承的情況,構造函數沿著從基類到子類的方向進行,而析構函數沿著相反方向執行。



C++進階之一