GeekBand C++ Week3 Notes

Week3 notes

A.面向對象編程,面向對象設計

composition,復合表示has-a

template>

class queue{

protected:

Sequencec; //底層容器

Public:

//以下玩完全利用c的操作函數完成

boolempty() const {return c.empty();}

size_typesize() const {return c.size();}

referencefront() {return c.front();}

referenceback() {return c.back();}

//

void push(constvalue_type& x) {c.push_back(x);}

void pop(){c.pop_front();}

};

a擁有b就叫composition,以上是一個特例,a擁有b,a所有的功能都用b來實現,但現實生活中確實有這種東西,deque的意思是兩端都可以進出。所以deque得功能比queue強大。這里做的是改裝一下,比如最后的pop方法,換了一個面貌出現,說不定deque有一百個功能,但現只包含了6個功能,而且名字可能變了,這是一種設計模式,叫做adaptor。變壓器,改造,適配,現在手上有一個東西完全滿足要用的功能,只是可能接口不同,名字不同,所以就改造一下,這里queue就是adaptor.

從內存的角度來理解。

40

Template

Class queue{

Protected:

Dequec;

}

16*2+4+4

template

class deque{

protected:

Itrstart;

Itr finish;

T** map;

Unsigned intmap_size;

}

4*4

template

struct Itr{

T* cur;

T*

T*

T*

}

復合關系下的構造和析構:

構造由內而外,container的構造函數首先調用component的default構造函數,然后才執行自己。

Container::container(…): component(){…};

析構由外而內,container的析構函數首先執行自己,再調用component的析構函數。

Container::~container(…) {…~component()};

這些部分編譯器自己會加上去,形成合理。構造函數是默認的這一個,如果這一個不符合的話,就要我們自己寫,自己調用內部的構造函數,輸入都要自己寫,但是析構函數只有一個所以不需要。

I’?

Delegation委托,composition byreference.ZX

String.hpp

Class StringRep;

Class String{

Public:

String();

String(constchar* s);

String(constString& s);

Stringoperator=(const String& s);

~String();

private:

StringRep*rep; //pimpl

};

#include “String.hpp”

namespace{

class stringRep{

friend class String;

StringRep(constchar* s);

~StringRep();

intcount;

char*rep;

}

};

兩個類之間用指針相連就叫委托,如果有了一個外部的就有一個內部,就叫composition,現在用指針相連,只有在要用到右邊的時候才用到,叫委托,也叫composition by reference,具體的實現都在右邊做,當左邊要用到的時候調用右邊的服務,這種寫法非常有名,pointer to implementation. Handle/body為什么這么有名呢?因為我們如果把類都寫成這樣的話,左手邊都不需要換,字符串如果要怎么變這個指針可以指向不同的實現類,右邊怎么變動都不影響左邊,也就不影響客戶端,這個手法也叫編譯防火墻,左邊都不需要管右邊。

但用指針三個人共享同一個hello要注意abc互相不知道他們引用同一個,當a改變的時候要單獨給你一份改,叫copy on write.

Inheritance繼承,表示is-a

Struct _List_node_base

{

_list_node_base*Mnext;

Listnodebase*_M_prev;

};

template

struct _List_node

:public_List_node_base

{

_Tp_M_data;

}

c++有三種繼承,使用public繼承就是is-a,如果你用public繼承但兩個類的關系不是is-a,將來有可能出錯。

繼承關系下的構造和析構。Derived派生類。從內存的角度來看子類的對象里頭有一個父類的base part,base class的dtor必須是virtual的,否則會出現undefined behavior

構造要由內而外,

derived的構造函數首先調用base的default構造函數,然后才執行自己。

Derivevd::derived(…): base(){…};

析構由外而內

derived的析構函數首先執行自己,然后才調用base的析構函數。

Derived::~derived(…) {…~base()};

繼承要搭配虛函數virtual function

B.虛函數與多態

虛函數與繼承

當我們使用繼承的時候要搭配虛函數,非虛函數non-virtual function是你不希望derived class重新定義(override,復寫)他。

虛函數是你希望derived class重新定義(override)它已有的默認定義。Override一定被用在虛函數被重新定義。

Pure virtual函數是你希望derived class一定要重新定義它,你對他沒有默認定義。和虛函數的區別是你根本沒有定義。

Class Shape{

Public:

Virtualvoid draw() const = 0;//pure virtual

Virtualvoid error(const std::string& msg);//impure virtual

IntobjectID() const;//non-virtual

}

class Rectangle: public Shape{…};

class Ellipse: public Shape {…};

CDocument::

OnFileOpen(){

Serialize()

}

讀的動作是serialize()

我們寫我們自己的子類

class CMyDoc:

publicCDocument{

virtualSeriallize() {…}

}

main(){

CmyDocmyDoc;

myDoc.OnFileOpen();

}

通過子類的對象調用父類的函數。函數的全名是CDocument::OnFileOpen(&myDoc);

23個設計模式之一Template

Method,模板方法,將一些函數延緩寫出來,我先幫你想好了你要寫一個應用程序你要有哪些功能,很多功能都是相同的,我先幫你預設好,具體的部分留到你自己的子類中去重構他。這里的CDocument中的OnFileOpen是應用框架,Application Framework,十多年前MFC Microsoft Foundation classes

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

如果子類繼承父類之外又有一個component,那哪個構造函數先被調用呢?

如果父類中有一個component的話又是怎么樣呢?

1父類,component,子類

委托加繼承關系

Office軟件中可以開多個窗口看同一個東西。或者是同一份數據可以用三種不同的形式觀察。要想有這種功能,有兩個CLASS一種是存儲,一種是表現。

Class Subject{

Intm_value;

Vectorm_views;

Public:

Voidattach(Observer* obs){

M_views.push_back(obs);

}

void set_val(intvalue){

m_value = value;

notify();

}

void notify(){

for(int I = 0; i< m_value.size();i++)

m_views[i]->update(this, m_value);

}

};

class Observer{

public:

virtualvoid update(Subject*sub, int value) = 0;

};

左邊是有一個delegation的關系,左邊要有注冊和注銷的功能。Attach實現注冊功能。

C.委托相關設計

委托加繼承

Composite

現在要寫一個file system,有目錄,有文件,目錄里面可以放文件,目錄還可以放到其他目錄里。window system,大窗口里面有小窗口。那應該使用哪些class,應該使用什么將他們聯系起來。

目錄系統。

Primitive,composite可以放左邊的primitive,也可以放自己,如果左邊和右邊寫一個父類,這樣兩邊都是is-a component,所以就可以寫成c:vector,不能放對象,要放指針,右邊這個東西是一個組合物,所以他應該具有一個函數add(e:component*),因為它又可以加左邊的東西,,也可以加右邊的東西,這樣兩個東西都可以接受。發現有很多解法都是要用到兩把武器。這種解法叫做composite是23個設計模式中的一個。

Class primitive: public Component{

Public:

Primitive(intval): Component(val) {}

};

class Component{

intvalue;

public:

Component(intval) {value = val;}

Virtualvoid add(component*) {}

};

class Composite: public component{

vectorc;

public:

composite(intval): component(val) {}

voidadd(component* elem) {

c.puch_back(elem);

}

};

prototype

我要創建未來

LandSatImage是一個子類,都有一個靜態的自己,很久以前寫好的框架要能看得到后來寫的東西,-LandSatImage(),負的代表private,#代表Protected,我們故意把構造函數設為私有,那在創建的時候私有的構造函數可以被調用起來嗎?可以,因為是自己人,不是外界在調用,我們就借用這個私有的構造函數,addPrototype(this).而且掛上去在父類中看得到。父類Image中,有addPrototype(p:Image*):void而且所有的子類都應該有一個函數clone():Image*,做的事情是return

new LandSatImage.通過原型這個對象可以調用clone這個函數,如果沒有這個原型的話。

D.復合,繼承關系下的構造和析構

繼承關系下的構造和析構

復合關系下的構造和析構

繼承加上復合關系下的構造和析構

我們要談的是class和class之間的關系,三種關系。當發生繼承時,子類對象里頭有一個父類的成分。豬是一種哺乳動物,豬里頭就應該有哺乳動物的成分,哺乳動物應該有動物的成分。由于有這樣的關系,當我們在探討構造和析構的時候,我們要注意由內而外,析構函數要先執行自己,再調用父類的析構。

繼承和復合關系下的構造和析構,子類的構造函數首先調用父類的default構造函數,然后調用component的default構造函數,最后才執行自己。

析構由外而內,子類的析構函數首先執行自己,然后調用component的析構函數,最后調用base的析構函數。

本次作業要求構造十個隨機矩形和隨機十個圓并根據他們的面積進行刪選,遇到的問題有一開始思考如何將兩個類的對象放在一個數組里,很普通的問題,說明肯定已經有完美的解決方案,多態的使用,即使用基類指針指向子類對象,這時一定要注意要在子類中使用的方法一般都要在基類中使用虛函數或者純虛函數先寫出來,再在下面的子類中進行重載。包含有純虛函數的類叫做虛類,那什么時候我們需要構建一個虛類呢?當類是一個抽象概念的時候,比如這個題目中形狀這個類,我們就要構建它為虛函數,因為沒有一個對象是一個形狀,我們也不會將這個類實例化。具體的做法是shape** a = new shape* [20],這樣就構建了一個指針數組,且數組也使用指針表示,第二個遇到的問題是在刪選出合適的對象后,我一開始想要調用拷貝賦值函數,發現很麻煩,實際上可以直接拷貝指針,省去很多問題。然后不需要建立兩個數組,可以用快慢指針的方法將符合要求的一個個拷貝到當前數組,并將不符合的刪除,注意在刪除的時候要將指針置為空指針,在刪除數組的時候要用delete[]。

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

推薦閱讀更多精彩內容