面向?qū)ο蟮某绦蛟O(shè)計(jì)
概述
- [x] 隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅僅對(duì)外提供接口和方法
- 優(yōu)點(diǎn):`隔離變化` `便于使用` `提高重用性` `提高安全性`
- 缺點(diǎn):`如果封裝太多,影響效率` `使用者不能知道代碼的具體實(shí)現(xiàn)`
- [x] 一個(gè)對(duì)象直接使用另一個(gè)對(duì)象的屬性和方法
- 優(yōu)點(diǎn):`減少重復(fù)的代碼` `繼承是多態(tài)的前提` `繼承增加了類的耦合性`
- 缺點(diǎn):`繼承在編譯時(shí)刻就定義,無法在運(yùn)行時(shí)刻改變父類繼承的實(shí)現(xiàn)` `父類通常至少定義了子類的部分行為匀借,父類的改變都可能影響子類的行為` `入股繼承下來的子類不適合解決新問題,父類必須重寫或替換,那么這種依賴關(guān)系就限制了靈活性扇雕,最終限制了復(fù)用性`
- [x] C++中有兩種多態(tài),`動(dòng)多態(tài)(運(yùn)行期多態(tài))`以及`靜多態(tài)(編譯器多態(tài))`窥摄,而靜多態(tài)主要通過模板實(shí)現(xiàn)镶奉,宏也是實(shí)現(xiàn)靜多態(tài)的一種途徑,動(dòng)多態(tài)在C++中是通過虛函數(shù)實(shí)現(xiàn)的溪王,即在基類中存在一些接口(一般為純虛函數(shù))腮鞍,子類必須重載這些接口,這樣通過使用基類的指針或者引用指向子類的對(duì)象莹菱,就可以實(shí)現(xiàn)調(diào)用子類對(duì)應(yīng)的函數(shù)的功能移国,動(dòng)多態(tài)的函數(shù)調(diào)用機(jī)制是執(zhí)行期才能進(jìn)行確定,所以它是動(dòng)態(tài)的
- [x] 接口的多種不同實(shí)現(xiàn)方式即為多態(tài)
- 優(yōu)點(diǎn):`大大提高了代碼的可復(fù)用性`
- 缺點(diǎn):`易讀性比較差道伟,調(diào)試?yán)щy` `模板只能定義在.h文件中迹缀,當(dāng)工程大了之后使碾,編譯時(shí)間較長`
- 對(duì)于某些函數(shù),基類希望它的派生類各自定義適合自身的版本祝懂,此時(shí)基類就將這些函數(shù)聲明成
虛函數(shù)
class Quote{
public:
std::string isbn() const;
virtual double net_price(std::size_n n) const;
};
- 派生類必須通過使用
派生類列表
明確指出它是從哪個(gè)基類繼承而來
class Bulk_quote : public Quote{
public:
double net_price(std::size_n) const override;
};
- C++11允許派生類顯式的注明它將使用哪個(gè)成員函數(shù)改寫基類的虛函數(shù)票摇,具體措施是在該函數(shù)的形參列表之后增加一個(gè)
override
關(guān)鍵字
virtual關(guān)鍵字解析
- 在類base中加了virtual關(guān)鍵字的函數(shù)就是虛擬函數(shù),基類的函數(shù)調(diào)用如果有virtual則根據(jù)多態(tài)性調(diào)用派生類砚蓬,如果沒有virtual則是正常的靜態(tài)函數(shù)調(diào)用,還是調(diào)用基類的
- virtual關(guān)鍵字與重載的區(qū)別
- [x] 重載的幾個(gè)函數(shù)必須在同一個(gè)類中灰蛙;覆蓋的函數(shù)必須在有繼承關(guān)系的不同的類中
- [x] 覆蓋的幾個(gè)函數(shù)必須函數(shù)名祟剔、參數(shù)、返回值都相同笙纤;重載函數(shù)必須函數(shù)名相同强霎,參數(shù)不同寞酿,參數(shù)不同的目的就是為了在函數(shù)調(diào)用的時(shí)候編譯器能夠通過參數(shù)來判斷程序是在調(diào)用哪個(gè)函數(shù)拉馋,這也就很自然地解釋了為什么函數(shù)不能通過返回值不同來重載龄句,因?yàn)槌绦蛟谡{(diào)用函數(shù)的時(shí)候很有可能不關(guān)心返回值岳遥,編譯器就無法從代碼中看出程序在調(diào)用哪個(gè)函數(shù)
- [x] 覆蓋的函數(shù)前必須加關(guān)鍵字virtual
- 重載和virtual沒有任何瓜葛,加不加都不影響重載的運(yùn)作
定義基類和派生類
定義基類
- 基類通常都應(yīng)該定義一個(gè)虛析構(gòu)函數(shù)裕寨,即使該函數(shù)不執(zhí)行任何實(shí)際操作也是如此
- 在C++語言中浩蓉,基類必須將它的兩種成員函數(shù)區(qū)分開來:
- [x] 一種是基類希望派生類進(jìn)行覆蓋的函數(shù),對(duì)于這種函數(shù)宾袜,基類通常將其定義為`虛函數(shù)`
- [x] 另一種是基類希望派生類直接繼承而不要改變的函數(shù)
- 當(dāng)我們使用指針或引用調(diào)用虛函數(shù)時(shí)捻艳,該調(diào)用將被動(dòng)態(tài)綁定,根據(jù)引用或指針?biāo)壎ǖ膶?duì)象類型不同庆猫,該調(diào)用可能執(zhí)行基類的版本认轨,也可能執(zhí)行某個(gè)派生類的版本
- 基類通過在其成員函數(shù)的聲明語句之前加上關(guān)鍵字virtual使得該函數(shù)執(zhí)行動(dòng)態(tài)綁定,任何構(gòu)造函數(shù)之外的非靜態(tài)函數(shù)都可以是虛函數(shù)
- 關(guān)鍵字virtual只能出現(xiàn)在類內(nèi)部的聲明語句之前而不能用于類外部的函數(shù)定義
- 如果基類把一個(gè)函數(shù)聲明稱虛函數(shù)月培,則該函數(shù)在派生類中隱式的也是虛函數(shù)
- 成員函數(shù)如果沒被聲明為虛函數(shù)嘁字,則其解析過程發(fā)生在編譯時(shí)而非運(yùn)行時(shí)
- 在某些時(shí)候基類中有這樣一種成員,基類希望派生類有權(quán)訪問該成員杉畜,同時(shí)禁止類外其他用戶訪問纪蜒,稱之為
(受保護(hù)的protected)
的成員
定義派生類
- 派生類必須使用
派生類列表
明確指出它是從哪個(gè)(哪些基類繼承而來的)
- 因?yàn)榕缮悓?duì)象中含有基類對(duì)應(yīng)的組成部分,所以我們能把派生類的對(duì)象當(dāng)成基類來使用此叠,而且我們也能將基類的指針或引用綁定到派生類對(duì)象中的基類部分上
- 編譯器會(huì)隱式地執(zhí)行派生類到基類的轉(zhuǎn)換
- 這種隱式特性意味著我們可以把派生類對(duì)象或派生類對(duì)象的引用在需要基類引用的地方纯续,同樣的,也可以把派生類對(duì)象的指針用在需要基類的地方
- 在派生類對(duì)象中含義與其基類對(duì)應(yīng)的組成部分灭袁,這一事實(shí)是繼承的關(guān)鍵所在
- 每個(gè)類控制它自己的成員初始化過程
- 派生類構(gòu)造函數(shù)同樣是通過構(gòu)造函數(shù)初始化列表來將實(shí)參傳遞給基類構(gòu)造函數(shù)的
- 派生類首先初始化基類的部分猬错,然后按照聲明的順序依次初始化派生類的成員
- 每個(gè)類負(fù)責(zé)定義各自的接口,要想與類的對(duì)象交互必須使用該類的接口茸歧,即使這個(gè)對(duì)象是派生類的基類部分也是如此
- 由上述原因倦炒,派生類對(duì)象不能直接初始化基類成員盡管從語法上來說我們可以在派生類構(gòu)造函數(shù)體內(nèi)給它的公有或私有或受保護(hù)的基類成員賦值,但最好不要這么做举娩,和使用基類的其他場(chǎng)合一樣析校,派生類應(yīng)該組合尋基類的接口构罗,并且通過調(diào)用基類的構(gòu)造函數(shù)來初始化那些從基類中繼承而來的成員
- 如果基類定義了一個(gè)靜態(tài)成員,則在整個(gè)繼承體系中只存在該成員的唯一定義智玻,不論從基類中派生出多少個(gè)派生類遂唧,對(duì)于每個(gè)靜態(tài)成員來說都只存在唯一的實(shí)例
- 靜態(tài)成員遵循通用的訪問權(quán)限控制,如果基類中的成員是private的吊奢,則派生類無權(quán)訪問它盖彭,假設(shè)某靜態(tài)成員是可訪問的,則我們既能通過某些基類使用它也能通過派生類使用它
- 入股我們想將某個(gè)類用作基類页滚,則該類必須已經(jīng)定義而非僅僅聲明
- 一個(gè)類不能派生它自身
- 一個(gè)類是基類召边,同時(shí)它也可以是一個(gè)派生類
- 有時(shí)我們會(huì)定義這樣一種類,我們不希望其他類繼承它裹驰,或者不想考慮它是否適合作為一個(gè)基類隧熙,為了實(shí)現(xiàn)這一目的,C++11新標(biāo)準(zhǔn)提供了一種防止繼承發(fā)生的方法幻林,即在類名字后面跟一個(gè)關(guān)鍵字
final
類型轉(zhuǎn)換與繼承
- 當(dāng)使用基類的引用(或指針)時(shí)贞盯,實(shí)際上我們并不清楚該引用(或指針)所綁定的對(duì)象的真實(shí)類型,該對(duì)象可能是基類的對(duì)象沪饺,也可能是派生類的對(duì)象
- 之所以存在派生類向基類的類型轉(zhuǎn)換是因?yàn)槊總€(gè)派生類對(duì)象都包含一個(gè)基類部分躏敢,而基類的引用或指針可以綁定到該基類部分上
- 一個(gè)基類的對(duì)象既可以以獨(dú)立的形式存在,也可以作為派生類對(duì)象的一部分存在有整葡,如果基類對(duì)象不是派生類的一部分件余,則它只含有基類定義的成員,而不含有派生類定義的成員
- 因?yàn)橐粋€(gè)基類的對(duì)象可能是派生類對(duì)象的一部分遭居,也可能不是啼器,所以不存在從基類向派生類的自動(dòng)類型轉(zhuǎn)換
- 即使一個(gè)基類指針或引用綁定在一個(gè)派生類對(duì)象上,也不能執(zhí)行從基類向派生類的轉(zhuǎn)換
- 派生類向基類的自動(dòng)類型轉(zhuǎn)換只對(duì)指針或引用類型有效魏滚,在派生類類型和積累類型之間不存在這樣的轉(zhuǎn)換
- 當(dāng)我們用一個(gè)派生類對(duì)象為一個(gè)基類對(duì)象初始化或賦值時(shí)镀首,只有該派生類對(duì)象中的基類部分會(huì)被拷貝、移動(dòng)或賦值鼠次,它的派生類部分將會(huì)被忽略掉
- 存在繼承關(guān)系的類型間的轉(zhuǎn)換規(guī)則
- [x] 從派生類向基類的類型轉(zhuǎn)換只對(duì)指針或引用類型有效
- [x] 基類向派生類不存在隱式類型轉(zhuǎn)換
- [x] 和任何其他成員一樣更哄,派生類向基類的類型轉(zhuǎn)換也可能會(huì)由于訪問受限而變得不可行
虛函數(shù)
- 當(dāng)某個(gè)虛函數(shù)通過指針或引用被調(diào)用時(shí),編譯器產(chǎn)生的代碼直到運(yùn)行時(shí)才能確定應(yīng)該調(diào)用哪個(gè)版本的函數(shù)腥寇,被調(diào)用的函數(shù)是與綁定到指針或引用上的對(duì)象的動(dòng)態(tài)類型相匹配的那一個(gè)
動(dòng)態(tài)綁定只有當(dāng)我們通過指針或引用調(diào)用虛函數(shù)時(shí)才會(huì)發(fā)生
-
OOP的核心思想是多態(tài)性成翩,我們把具有繼承關(guān)系的多個(gè)類型成為多態(tài)類型,因?yàn)槲覀兡苁褂眠@些類型的
多種形式而無需在意它們的差異赦役,引用或指針的靜態(tài)類型與動(dòng)態(tài)類型不同這一事實(shí)正是C++語言支持多態(tài)性的根本所在
- 當(dāng)且僅當(dāng)通過指針或引用調(diào)用虛函數(shù)時(shí)麻敌,才會(huì)在運(yùn)行時(shí)解析該調(diào)用,也只有在這種情況下對(duì)象的動(dòng)態(tài)類型才有可能與靜態(tài)類型不同
當(dāng)我們?cè)谂缮愔懈采w了某個(gè)虛函數(shù)時(shí)掂摔,可以再一次使用virtual關(guān)鍵字指出該函數(shù)的性質(zhì)术羔,但并不必須赢赊,因?yàn)橐坏┠硞€(gè)函數(shù)被聲明為虛函數(shù),則在所有派生類中它都是虛函數(shù)
- 一個(gè)派生類的函數(shù)如果覆蓋了某個(gè)繼承而來的虛函數(shù)级历,則它的形參類型必須與被它覆蓋的基類函數(shù)完全一致释移,同樣,派生類中虛函數(shù)的返回類型也必須與基類函數(shù)匹配(當(dāng)類的虛函數(shù)返回類型是類本身的指針或引用時(shí)上述規(guī)則無效)
- 基類中的虛函數(shù)在派生類中隱含地也是一個(gè)虛函數(shù)寥殖,當(dāng)派生類覆蓋了某個(gè)虛函數(shù)時(shí)玩讳,該函數(shù)在基類中的形參必須與派生類中的形參嚴(yán)格匹配
- 在C++11中我們可以使用override關(guān)鍵字來來說明派生類中的虛函數(shù)
- 如果虛函數(shù)使用默認(rèn)實(shí)參,則基類和派生類中定義的默認(rèn)實(shí)參最好一致
- 通常情況等下嚼贡,只有成員函數(shù)(或友元)中的代碼才需要使用作用域運(yùn)算符來回避虛函數(shù)的機(jī)制
- 如果一個(gè)派生類虛函數(shù)需要調(diào)用它的基類版本熏纯,但是沒有使用作用域運(yùn)算符,則在運(yùn)行時(shí)該調(diào)用將被解析為對(duì)派生類版本自身的調(diào)用粤策,從而導(dǎo)致無限遞歸
抽象基類
- 在虛函數(shù)體的位置(即在聲明語句的分號(hào)之前)書寫
=0
就可以將一個(gè)函數(shù)說明為純虛函數(shù)樟澜,其中=0
只能出現(xiàn)在類內(nèi)部的虛函數(shù)聲明語句處
- 含有純虛函數(shù)的類是
抽象基類
- [x] `抽象基類`負(fù)責(zé)定義接口,而后續(xù)的其他類可以覆蓋該接口
- 我們不能直接創(chuàng)建一個(gè)抽象基類的對(duì)象
- 派生類構(gòu)造函數(shù)只初始化它的直接基類
訪問控制與繼承
-
protected說明符
可以看作是public
和private
中和后的產(chǎn)物
- [x] 和私有成員類似掐场,受保護(hù)的成員對(duì)于類的用戶來說是不可訪問的
- [x] 和公有成員類似往扔,受保護(hù)的成員對(duì)于派生類的成員和友元來說是可訪問的
- [x] 派生類的成員或友元只能通過派生類對(duì)象來凡哥維納基類的受保護(hù)成員,派生類對(duì)于一個(gè)基類對(duì)象中的受保護(hù)成員沒有任何訪問特權(quán)
- 某個(gè)類對(duì)其繼承而來的成員的訪問權(quán)限受到兩個(gè)因素影響
- [x] 在基類中該成員的訪問說明符
- [x] 在派生類的派生列表中的訪問說明符
- 對(duì)于代碼中的某個(gè)給定節(jié)點(diǎn)來說熊户,如果1基類的公有成員是可訪問的,則派生類向基類的類型轉(zhuǎn)換也是可訪問的吭服,反之則不行
- 就像友元關(guān)系不能傳遞一樣嚷堡,友元關(guān)系同樣也不能繼承,基類的友元在訪問派生類成員時(shí)不具有特殊性艇棕,類似的蝌戒,派生類的友元也不能隨意訪問基類的成員
- 不能繼承友元關(guān)系,每個(gè)類各自負(fù)責(zé)控制各自成員的訪問權(quán)限
- 通過在類的內(nèi)部使用
using
聲明語句沼琉,我們可以將該類的直接或間接基類中的任何可訪問成員標(biāo)記出來北苟,using聲明語句中名字的訪問權(quán)限由該using聲明語句之前的訪問說明符決定
class Base{
public:
std::size_t size() const {return n;}
protected:
std::size_t n;
};
class Derived : private Base{ //private繼承
public:
using Base::size;
protected:
using Base::n;
};
- 派生類只能為那些它可以訪問的名字提供using聲明
- 默認(rèn)的繼承保護(hù)級(jí)別
class Base{/***/};
struct D1 : Base {/***/}; //struct默認(rèn)public繼承
class D2 : Base {/***/}; //class默認(rèn)private繼承
人們常常有一種錯(cuò)覺,認(rèn)為在使用struct關(guān)鍵字和class關(guān)鍵字定義的類之間還有更深層次的差別打瘪,事實(shí)上友鼻,唯一的差別就是默認(rèn)成員訪問說明符以及默認(rèn)派生訪問說明符,除此之外闺骚,再無其他不同之處
- 一個(gè)私有派生類最好顯式的將private聲明出來彩扔,而不要僅僅依賴于默認(rèn)的設(shè)置,顯式聲明的好處是可以令私有繼承關(guān)系清晰明了僻爽,不至于產(chǎn)生誤會(huì)
繼承中的類作用域
- 除了覆蓋繼承而來的虛函數(shù)中虫碉,派生類最好不要重用其他定義在基類中的名字
- 名字查找先于類型檢查
- 如果派生類的成員與基類的某個(gè)成員同名,則派生類將在其作用域內(nèi)隱藏該基類成員胸梆,即使派生類成員和基類成員的形參列表不一致敦捧,基類成員也仍然會(huì)被隱藏掉
strquct Base{
int memfcn();
};
struct Derived : Base{
int memfcn(int ); //隱藏基類的memfcn
};
Derived d;
Base b;
b.memfcn(); //調(diào)用Base:memfcn
d.memfcn(10); //調(diào)用Derived:memfcn
d.memfcn(); //錯(cuò)誤:參數(shù)列表為空的me'mfcn被隱藏了
d.Base:memfcn(); //正確:調(diào)用Base:memfcn
- 基類與派生類中的虛函數(shù)必須有相同的形參列表须板,假如基類與派生類的虛函數(shù)接受的實(shí)參不同,則我們無法通過基類的引用或指針調(diào)用派生類的虛函數(shù)了
對(duì)于虛函數(shù)的執(zhí)行兢卵,編譯器產(chǎn)生的代碼將在運(yùn)行時(shí)確定使用虛函數(shù)的哪個(gè)版本习瑰,判斷的根據(jù)是該指針?biāo)壎▽?duì)象的真實(shí)類型
構(gòu)造函數(shù)與拷貝控制
虛析構(gòu)函數(shù)
- 在基類中將析構(gòu)函數(shù)定義成虛函數(shù)可以確保執(zhí)行正確的析構(gòu)函數(shù)版本
- 如果基類的析構(gòu)函數(shù)不是虛函數(shù),則delete一個(gè)指向派生類對(duì)象的基類指針將產(chǎn)生未定義的行為
- 一個(gè)基類總是需要析構(gòu)函數(shù)济蝉,而且它能將析構(gòu)函數(shù)設(shè)定為虛函數(shù)杰刽,如果一個(gè)類定義額析構(gòu)函數(shù),即使它通過=default的形式使用了合成版本王滤,編譯器也不會(huì)為這個(gè)類合成移動(dòng)操作
合成拷貝控制與繼承
- 對(duì)于派生類的析構(gòu)函數(shù)來說贺嫂,它除了銷毀派生類自己的成員外,還負(fù)責(zé)銷毀派生類的直接基類雁乡;該基類又銷毀它自己的直接基類第喳,以此類推直至繼承鏈的頂端
派生類的拷貝控制成員
- 派生類的構(gòu)造函數(shù)在其初始化階段不但要初始化派生類自己的成員,還負(fù)責(zé)初始化派生類對(duì)象的基類部分踱稍,因此曲饱,派生類的拷貝和移動(dòng)構(gòu)造函數(shù)在拷貝和移動(dòng)自有成員的同時(shí),也要拷貝和移動(dòng)基類部分的成員珠月,類似的扩淀,派生類賦值運(yùn)算符也必須為其基類部分的成員賦值
當(dāng)派生類定義了拷貝或移動(dòng)操作時(shí),該操作負(fù)責(zé)拷貝或移動(dòng)包括基類部分成員在內(nèi)的整個(gè)對(duì)象
- 在默認(rèn)情況下啤挎,基類默認(rèn)構(gòu)造函數(shù)初始化派生類對(duì)象的基類部分驻谆,如果我們想拷貝或移動(dòng)基類部分,則必須在派生類的構(gòu)造函數(shù)初始值列表中顯式地使用基類地拷貝(或移動(dòng))構(gòu)造函數(shù)
- 與拷貝和移動(dòng)構(gòu)造函數(shù)一樣庆聘,派生類地賦值運(yùn)算符也必須顯式地為其基類部分賦值
- 如果構(gòu)造函數(shù)或析構(gòu)函數(shù)調(diào)用了某個(gè)虛函數(shù)胜臊,則我們應(yīng)該執(zhí)行與構(gòu)造函數(shù)或析構(gòu)函數(shù)所屬類型相對(duì)于地虛函數(shù)版本
繼承的構(gòu)造函數(shù)
- 類不能繼承默認(rèn)、拷貝和移動(dòng)構(gòu)造函數(shù)伙判,如果派生類沒有定義這些構(gòu)造函數(shù)象对,則編譯器將為派生類合成它們
- 派生類繼承基類構(gòu)造函數(shù)的方式提供了一條直接注明基類名using聲明語句
class Bulk_quote : public Disc_quote{
public:
using Disc_quote::Disc_quote; //繼承Disc_quote的構(gòu)造函數(shù)
double net_price() const;
};
容器與繼承
- 當(dāng)派生類對(duì)象被賦值給基類對(duì)象時(shí),其中的派生類部分將被'切掉'宴抚,因此容器和存在繼承關(guān)系的類型無法被兼容
- 當(dāng)我們希望在容器中存放具有繼承關(guān)系的對(duì)象時(shí)勒魔,我們實(shí)際上存放的通常是基類的指針(更好的選擇是智能指針),和往常一樣酱塔,這些指針?biāo)笇?duì)象的動(dòng)態(tài)類型可能是基類類型沥邻,也可能是派生類類型
繼承和組合
- 當(dāng)我們令一個(gè)類公有的繼承另一個(gè)類時(shí),派生類應(yīng)當(dāng)反應(yīng)與基類的‘是一種(Is A)’關(guān)系羊娃,在設(shè)計(jì)良好的類體系中唐全,公有派生類的對(duì)象應(yīng)該可以用在任何需要基類對(duì)象的地方
- 類型之間的另一種常見關(guān)系是‘有一個(gè)(Has A)’關(guān)系,具有這種關(guān)系的類暗含成員的意思
小結(jié)
- 繼承使得我們可以編寫一些新的類,這些類既能共享其基類的行為邮利,又能根據(jù)需要覆蓋或添加行為
- 動(dòng)態(tài)綁定使得我們可以忽略類型之間的差異弥雹,其機(jī)理是在運(yùn)行時(shí)根據(jù)對(duì)象的動(dòng)態(tài)類型來選擇運(yùn)行哪個(gè)版本
- 繼承和動(dòng)態(tài)綁定的結(jié)合使得我們能夠編寫具有特定類型行為但又獨(dú)立于類型的程序
- 在C++中,動(dòng)態(tài)綁定只作用于虛函數(shù)延届,并且需要通過指針或引用調(diào)用
- 在派生類對(duì)象中包含有與它的每個(gè)基類對(duì)應(yīng)的的子對(duì)象剪勿,因?yàn)樗信缮悓?duì)象都含有基類部分,所以我們能將派生類的引用或指針轉(zhuǎn)換為一個(gè)可訪問的基類引用或指針
- 當(dāng)執(zhí)行派生類的構(gòu)造方庭、拷貝厕吉、移動(dòng)和賦值操作時(shí),首先構(gòu)造械念、拷貝头朱、移動(dòng)和賦值其中的基類部分,然后才輪到派生類部分龄减,析構(gòu)函數(shù)的執(zhí)行順序剛好相反项钮,先銷毀派生類,接下來執(zhí)行基類子對(duì)象的析構(gòu)函數(shù)
- 基類通常應(yīng)該定義一個(gè)虛析構(gòu)函數(shù)希停,即使基類根本不需要析構(gòu)函數(shù)也最好這么做烁巫,將基類的析構(gòu)函數(shù)定義為虛函數(shù)的原因是為了確保當(dāng)我們刪除一個(gè)基類指針,而該指針實(shí)際指向一個(gè)派生類對(duì)象時(shí)宠能,程序也能正常運(yùn)行