[GeekBand] C++面向?qū)ο蟪绦蛟O(shè)計(jì)-2

一個(gè)類(lèi)的對(duì)象的生命歷程如下:

申請(qǐng)內(nèi)存——>初始化列表——>構(gòu)造函數(shù)——>參與運(yùn)算——>析構(gòu)函數(shù)——>釋放內(nèi)存。

在上述過(guò)程中存在三個(gè)特殊函數(shù)(Big Three):拷貝構(gòu)造函數(shù)、拷貝復(fù)制函數(shù)、析構(gòu)函數(shù)。

拷貝構(gòu)造函數(shù)(copy constructor function)在以下三種情況下將被調(diào)用:

1. 定義一個(gè)對(duì)象時(shí),以本類(lèi)另一個(gè)對(duì)象作為初始值,發(fā)生復(fù)制構(gòu)造;

2. 如果函數(shù)的形參是類(lèi)的對(duì)象,調(diào)用函數(shù)時(shí),將使用實(shí)參對(duì)象初始化形參對(duì)象,發(fā)生復(fù)制構(gòu)造;

3. 如果函數(shù)的返回值是類(lèi)的對(duì)象,函數(shù)執(zhí)行完成返回主調(diào)函數(shù)時(shí),將使用return語(yǔ)句中的對(duì)象初始化一個(gè)臨時(shí)無(wú)名對(duì)象,傳遞給主調(diào)函數(shù),此時(shí)發(fā)生復(fù)制構(gòu)造。

對(duì)象間的拷貝分為兩種情況,一種叫作淺拷貝,另一種叫作深拷貝。淺拷貝將一個(gè)對(duì)象相應(yīng)的成員數(shù)據(jù)賦給另一個(gè)對(duì)象,但是他們所指向的是同一塊內(nèi)存中的數(shù)據(jù)。深拷貝將一個(gè)對(duì)象相應(yīng)的成員數(shù)據(jù)賦給另一個(gè)對(duì)象,但是他們占用不同的內(nèi)存存儲(chǔ)相同的成員數(shù)據(jù)。

如果數(shù)據(jù)成員中不包含指針的話就用淺拷貝構(gòu)造函數(shù)就行,如果包含了指針就需要用到深拷貝構(gòu)造函數(shù),即為該指針在堆上開(kāi)辟一塊內(nèi)存空間。若使用淺拷貝,兩個(gè)指針將指向同一個(gè)內(nèi)存空間,當(dāng)析構(gòu)時(shí),該內(nèi)存空間將被釋放兩次。


關(guān)于堆(Heap)、棧(Stack):

一般說(shuō)的堆棧指的是就是棧。

棧(操作系統(tǒng)):由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類(lèi)似于數(shù)據(jù)結(jié)構(gòu)中的棧。

棧使用的是一級(jí)緩存, 他們通常都是被調(diào)用時(shí)處于存儲(chǔ)空間中,調(diào)用完畢立即釋放。

堆(操作系統(tǒng)): 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收,分配方式倒是類(lèi)似于鏈表。

堆則是存放在二級(jí)緩存中,生命周期由虛擬機(jī)的垃圾回收算法來(lái)決定(并不是一旦成為孤兒對(duì)象就能被回收),所以調(diào)用這些對(duì)象的速度要相對(duì)來(lái)得低一些。

堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹(shù),如:堆排序。

棧(數(shù)據(jù)結(jié)構(gòu)):一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。

詳解參考:http://www.cnblogs.com/kira2will/p/3957545.html


如果沒(méi)有自定義的析構(gòu)函數(shù)則系統(tǒng)自動(dòng)生成,析構(gòu)函數(shù)在對(duì)象銷(xiāo)毀時(shí)自動(dòng)調(diào)用,析構(gòu)函數(shù)沒(méi)有返回值、沒(méi)有參數(shù)也不能重載。

使用運(yùn)算符 new 可以申請(qǐng)單個(gè)內(nèi)存時(shí)可直接初始化,如?int *p=new int(20)。new 內(nèi)部調(diào)用 malloc 函數(shù),先分配內(nèi)存,再調(diào)用構(gòu)造函數(shù)。申請(qǐng)內(nèi)存時(shí)存在風(fēng)險(xiǎn),要處理p==NULL的狀況。申請(qǐng)內(nèi)存之后必須用運(yùn)算符 delete 釋放,delete 內(nèi)部先調(diào)用析構(gòu)函數(shù),再釋放內(nèi)存。new 需要與 delete 搭配使用,array new 則必須與 array delete 搭配使用。

? ?String* p = new String[3];

? ? ...

? ? delete[] p;

類(lèi)之間的三大關(guān)系分別為復(fù)合、委托與繼承。復(fù)合表示 has-a,構(gòu)造時(shí)由內(nèi)而外,析構(gòu)時(shí)有外而內(nèi)。委托同樣表示 has-a,可以看作一種引用形式的復(fù)合。繼承表示 is-a,其構(gòu)造由內(nèi)而外,即先調(diào)用基類(lèi)的構(gòu)造函數(shù),再調(diào)用派生類(lèi)的構(gòu)造函數(shù);析構(gòu)由外而內(nèi),即先調(diào)用派生類(lèi)的析構(gòu)函數(shù),再調(diào)用基類(lèi)的析構(gòu)函數(shù)。

Container::Container(...): Component() { ... };

Container::~Container(...) { ... ~Component() };

Derived::Derived(...): Base() { ... };

Derived::~Derived(...) { ... ~Base() };

幾種設(shè)計(jì)模式概述

Singleton 模式:Singleton 是對(duì)全局變量的取代策略,保證一個(gè)類(lèi)只能有一個(gè)實(shí)例,并提供一個(gè)全局唯一的訪問(wèn)點(diǎn)。

Strategy 模式:定義了算法家族,分別封裝起來(lái),讓他們之間可以互相替換,此模式讓算法的變化,不會(huì)影響到使用算法的客戶。

Adapter 模式:將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類(lèi)可以一起工作。

pImpl 模式:將客戶與所有關(guān)于類(lèi)的私有部分的知識(shí)隔離開(kāi),其主要作用是解開(kāi)類(lèi)的使用接口和實(shí)現(xiàn)的耦合,可以作為編譯防火墻。

Template Method 模式:定義一個(gè)操作中的算法的骨架。而將一些步驟延遲到子類(lèi)中,模板方法使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

Observer 模式:觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新自己

Composite 模式:將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

Prototype 模式:用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容