第四周 C++面向對象高級編程(下)Boolan

1. 導讀

我們的目標

  • 在先前基礎課程所培養的正規、大氣的編程素養上,繼續探討更多技術。
  • 泛型編程(Generic Programming)和面向對象編程(Object-Oriented Programming)雖然分屬不同思維,但它們正是 C++的技術主線,所以本課程也討論template(模板)。
  • 深入探索面向對象的繼承關系(inheritance)所形成的對象模型(Object Model),包括隱藏于底層的 this 指針,vptr(虛指針),vtbl(虛表),virtual mechanism(虛機制),以及虛函數(virtual functions)造成的 polymorphism(多態)效果。

2. 類型轉換

轉換有兩種,一種是轉出去,一種是轉過來。

2.1 Conversion Function 轉換函數

轉換函數的作用是轉出去,把這個類的值轉換成其他的類型。


Conversion Function
operator double() const {……;}

定義了一個轉換為 double 的函數,
沒有參數,轉換時不會帶有參數。
不寫返回類型,返回類型就是名稱里這個double

  • 如果不改變值,就該加 const,否則后面可能會出錯。
  • 只要認為合理,可以設計好幾個轉換函數。

模板的偏特化?
操作符重載

2.2 只有一個參數的構造函數

只有一個參數的構造函數可以將一個 int 或 float 值轉換為該類對象。

2.2.1 non-explicit-on-argument ctor

non-explicit-on-argument ctor
Fraction (int num, int den=1): m_numerator(num), m_denominator(den) { }

分母默認是1,這樣一個值構造為對象時,實際值不變。

Fraction operator+(const Fraction& f) { }

只能分數加分數

Fraction d2=f+4;

4可以轉換為 Fraction,因為有一個構造函數只有一個int 參數。

2.2.2 conversion function vs. non-explicit-one argument ctor

conversion function vs. non-explicit-one argument ctor

當轉換函數與非顯式聲明的一個參數的構造函數同時存在時,就會出現歧義。因為兩種方式都可以編譯。
多于一條路徑可以編譯,就會出現歧義,編譯器就會報錯。

[Error] ambiguous

2.2.3 explicit-one-argument ctor

explicit-one-argument ctor

顯式聲明就可以避免這個問題。

explicit Fraction(int num, int den=1):……

此時就會調用構造函數,而不會調用 double 轉換函數。

conversion function

3. 模仿的類

3.1 pointer-like classes

設計一個類,模擬 pointer

3.1.1 關于智能指針

不同的語法

->用掉后,還有一個->,所以

sp->method();
px->method(); //轉換完依舊有->

3.1.2 關于迭代器

迭代器中的指針操作

注意操作符重載
++ -- 適用于指針移動
Paste_Image.png

return (*node).data;  //取的是node 指向的塊的數據
return &(operator()); //返回迭代器中內容的指針,而不是指向迭代器塊的 node 的指針。

3.2 function-like classes,所謂仿函數

function-like classes
Paste_Image.png
Paste_Image.png
Paste_Image.png

unary_function 一個操作數
binary_function 兩個操作數

4. namespace 經驗談

namespace
namespace jj01
{
}//namespace

5. 模板 template

5.1 class template

class template
template<typename T>

5.2. Function Template

Function Template
template <class T>

5.3 Member Template

Member Template
template <class T1, class T2>
struct pair {
……
  template <class U1, class U2>
  ……
}
Paste_Image.png
Paste_Image.png
Base1* ptr = new Derived1; //up-cast
shared_ptr<Base1>sptr(new Derived1); // 模擬 up-cast

5.4 specialization,模板特化

specialization
template<class Key>
struct hash {  } ;
template<>
struct hash<char> {   };

泛化對應特化,共性中的個性,用來應對特例。

5.4.1 partial specialization,模板偏特化

又稱為局部特化

5.4.1.1 個數的偏

Paste_Image.png

< >尖括號內叫做模板參數

class vector<bool, Alloc> { };   // Alloc沒改變,而 bool 設定了。

一定要從左到右,不能跳,不能135固定,24改變。

5.4.1.2 范圍的偏

范圍的偏

指針指向的偏

class c<T*> {   };  // 限定為指針

如果 T 是指針,使用偏特化模板。

5.5 template template parameter,模板模板參數

5.5.1 容器需要參數

容器需要參數
using Lst = list<T, allocator<>>;

模板需要好幾個參數,必須替換

5.5.2 智能指針

智能指針

對應 SmartPtr,可以是……,不可以是……

5.5.3 這不是模板模板參數

這不是模板模板參數

已經綁定了,必須是這個,所以就沒有模糊地帶了。

6. 關于 C++ 標準庫

Paste_Image.png

所有的容易算法都要用一遍。
編譯器需要設定到 C++ 11

6.1 variadic templates (since C++11)

variadic templates

6.2 auto (since C++11)

auto

用 auto 時一定要讓編譯器能推出來。

auto ite = find(……)

find 的類型就是 auto 給 ite 的類型。


Paste_Image.png

auto 不能亂用,太長了、寫不出來可以用。
我們一定要知道每個變量的定義是什么。

ranged-bas for (since C++11)

ranged-bas for
for ( decl : coll ) //左邊是一個變量,右邊必須是一個collector,容器
for ( int i : { 2, 3, 5, 7 } ){ }
vector<double> vec;
……
for ( auto elem : vec ) { cout << elem << endl ;} //傳值
for ( auto& elem : vec ) { elem *= 3; } //傳引用,盡量傳引用

15. reference(引用)

reference

聲明時一定要有初值,設完之后就不能再變了。


reference

object 和其 reference 的大小相同,地址也相同(全都是假象)
???那么新建一個 reference 會讓程序新占用多少內存呢?

常見用途

常見用途

函數傳參

void func3(Cls& obj) { obj.xxx(); }
func3(obj);

reference 通常不用于聲明變量,而用于參數類型和返回類型的描述。
相同聲明結構,僅僅傳遞引用和變量,會導致模糊,簽名相同,所以不能同時存在。
是否加const,
???有什么區別?
加 const 會改變簽名,是可以定義的。

7. 復合&繼承關系下的構造和析構

7.1 Composition(復合)關系下的構造和析構

Composition(復合)關系下的構造和析構

Container 在外 Component 在內

7.2 Inheritance(繼承)關系下的構造和析構

Inheritance(繼承)關系下的構造和析構

Derive在外,Base 在內
由內而外構建
由外而內析構
子類析構函數會自動調用父類析構函數

Inheritance + Composition 關系下的構造和析構

Inheritance + Composition 關系下的構造和析構

不同編譯器可能不同
觀察到的結論是先調用 Base,后調用 Component

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375

推薦閱讀更多精彩內容