c++面向对象的程序设计
面向?qū)ο蟪绦蛟O(shè)計的核心思想是數(shù)據(jù)抽象(封裝)、繼承、動態(tài)綁定(多態(tài))。通過數(shù)據(jù)抽象,我們將類的接口(函數(shù))與實(shí)現(xiàn)(數(shù)據(jù)成員)分離;使用繼承,可以定義相似的類型并對相似關(guān)系建模;使用動態(tài)綁定,一定程度上忽略相似類型的區(qū)別,以同一的方式使用它們的對象。
派生類繼承基類,基類定義所有類共有的成員,而每個派生類定義各自特有的成員。
1、基類和派生類
(1)基類
基類與一般類的定義相同:
class A{
int a;
};
如果將某個類用作基類,則該類必須已經(jīng)定義而非聲明。在類名后添加final關(guān)鍵字可以防止繼承。
(2)派生類
派生類需要使用派生類列表,來指明繼承自哪些基類,每個基類前面可以由訪問說明符private、protected、public:
class B:public A{
double b;
};
派生類繼承基類的所有成員,但是對基類成員的訪問權(quán)限與訪問說明符有關(guān)。派生類可以添加新的成員。
2、虛函數(shù)
對于某些函數(shù),派生類需要定義自己的函數(shù)與基類的版本做適當(dāng)改變,此時基類可以將這些函數(shù)聲明添加virtual關(guān)鍵字變成虛函數(shù):
virtual int fun(int)const;
- 任何構(gòu)造函數(shù)之外的非靜態(tài)函數(shù)都可以是虛函數(shù),
- 關(guān)鍵字virtual只能出現(xiàn)在類內(nèi)部的聲明語句中,而不能用于外部的函數(shù)定義。
- 如果接類把一個函數(shù)聲明成虛函數(shù),該函數(shù)在派生類中也是虛函數(shù)。
- 如果函數(shù)被聲明成虛函數(shù),則其解析過程發(fā)生在運(yùn)行時,否則發(fā)生在編譯時。
派生類可以不改寫基類的虛函數(shù),直接繼承;如果有需要覆蓋,則必須要對重新定義的虛函數(shù)進(jìn)行聲明:
int fun(int)const override;;
具體做法是在形參列表后面、const成員函數(shù)的const關(guān)鍵字后面、引用成員函數(shù)的引用限定符后面添加一個關(guān)鍵字override。
(1)虛函數(shù)與默認(rèn)實(shí)參
如果我們通過基類的引用或指針調(diào)用了虛函數(shù),即使實(shí)際運(yùn)行的是派生類的版本,我們也使用基類中定義的默認(rèn)實(shí)參,此時傳入派生類函數(shù)的是基類函數(shù)定義的默認(rèn)實(shí)參。因此,如果虛函數(shù)使用了默認(rèn)實(shí)參,基類和派生類中定義的默認(rèn)實(shí)參最好一致。
(2)回避虛函數(shù)機(jī)制
如果我們希望代碼執(zhí)行某個版本的虛函數(shù),使用作用域運(yùn)算符實(shí)現(xiàn)這一目的:
p->A::fun();
該代碼強(qiáng)行調(diào)用A的fun函數(shù),而不管實(shí)際指向的對象類型是什么。通常當(dāng)一個派生類的虛函數(shù)調(diào)用它覆蓋的基類虛函數(shù)版本時,我們需要用到回避虛函數(shù)的默認(rèn)機(jī)制。
(3)純虛函數(shù)
純虛函數(shù)是在虛函數(shù)的基礎(chǔ)上發(fā)展而來,通過對繼承的虛函數(shù)重新聲明,通過在參數(shù)列表后面后面添加=0來聲明一個純虛函數(shù):
void fun()=0;//fun必須在其基類中是虛函數(shù)
- =0只能出現(xiàn)在類內(nèi)部的虛函數(shù)聲明語句處。
- 純虛函數(shù)可以只聲明不定義。
- 含有純虛函數(shù)的類是抽象類,派生類對象如果沒有覆蓋抽象的基類,則其也是抽象類。
- 我們不能創(chuàng)建一個抽象類的對象,可以定義其派生類的對象,前提是派生類覆蓋了基類的純虛函數(shù)。
3、動態(tài)綁定
(1)派生類到基類的類型轉(zhuǎn)換
因?yàn)榕缮悓ο笾泻信c其基類對應(yīng)的組成部分,所以我們能把派生類對象當(dāng)作基類來用:
A ItemA;
B itemB;
A *pa=&itemA;
pa=&itemB;//pa指向itemB的A類部分
A &ra=itemB;//ra綁定到itemB的A類部分
上述的轉(zhuǎn)換稱為派生類到基類的類型轉(zhuǎn)換。
函數(shù)的運(yùn)行版本根據(jù)實(shí)參的具體類型(指針或引用指向的是基類還是派生類)決定使用哪個虛函數(shù),這種在運(yùn)行時選擇函數(shù)的版本被稱為動態(tài)綁定(運(yùn)行時綁定)。動態(tài)綁定只有在我們通過指針或引用調(diào)用虛函數(shù)時才會發(fā)生。
(1)靜態(tài)類型和動態(tài)類型
表達(dá)式的靜態(tài)類型在編譯時知道,它是變量聲明是的類型或表達(dá)式生成的類型;動態(tài)類型是變量或表達(dá)式表示的內(nèi)存中的對象的類型,動態(tài)類型在運(yùn)行時才知。
如果表達(dá)式既不是引用也不是指針,則它的類型永遠(yuǎn)與靜態(tài)類型一致。
之所以存在派生類向基類的類型轉(zhuǎn)換時因?yàn)槊總€派生類對象都包含了基類的那部分,而基類的引用或指針可以綁定到該基類部分上。而不能將派生類的指針或引用指向基類,因?yàn)橹羔樋赡茉L問基類不存在的派生類成員。
基類指向派生類——可以
派生類指向基類——不行
3、派生類構(gòu)造函數(shù)
盡管從語法上來說我們可以在派生類構(gòu)造函數(shù)體內(nèi)給它的公有或受保護(hù)的基類成員賦值,但最好不要這么做,要想與類的對象交互必須使用該類的接口,即使是派生類,在初始化對象的基類部分時也只能調(diào)用基類的構(gòu)造函數(shù)來初始化那些從基類繼承而來的成員。
每個類控制它自己的成員初始化過程。
派生類構(gòu)造函數(shù)是通過構(gòu)造函數(shù)初始化列表來將實(shí)參傳遞給基類構(gòu)造函數(shù)的:
B( int va,double vb):A(va),b(vb){}
首先初始化基類部分,然后按照聲明順序初始化派生類的成員。
4、繼承與靜態(tài)成員
如果基類定義了一個靜態(tài)成員,則在整個繼承體系中只存在該成員的唯一定義,不論從基類繼承了多少個派生類,對于每個靜態(tài)成員來說只有一個。
?5、繼承與訪問說明符
訪問說明符public、protected、private。
(1)基類中成員的訪問說明符
public:誰都能訪問。
private:只有自己類的成員函數(shù)或其友元能訪問。
protected:自己類、友元、其派生類的成員、派生類的友元都能訪問。但派生類的成員或派生類的友元只能訪問派神類繼承基類的那部分受保護(hù)成員,不能訪問基類對象中的受保護(hù)成員。但是基類的友元可以訪問基類對象中的所有成員。
總結(jié)就是:
- 成員函數(shù)能訪問自己類的所有成員,
- 友元也能訪問友元類的所有成員。
- 派生類能和其友元能訪問從基類繼承來的的public和protected成員。
- 派生類和其友元不能訪問基類對象的protected和private成員。
(2)派生列表的訪問說明符
派生列表的訪問說明符的作用是將繼承的基類中成員的訪問說明符升級,限制派生類的對象(用戶)對這些成員所能進(jìn)行的操作;派生類的成員函數(shù)對基類所能進(jìn)行的操作沒有任何影響,有權(quán)限的還是有權(quán)限,無權(quán)限的還是沒有權(quán)限。
public:成員的訪問說明符沒變,派生類用戶可以訪問基類中的public成員。
protected:public變成protected,派生類用戶不能訪問基類的所有成員。
private:所有成員變成private,派生類用戶不能訪問基類的所有成員。
(3)struct和class的區(qū)別
前面說過二者的區(qū)別是默認(rèn)的訪問說明符,一個是public一個是private
現(xiàn)在添加一個區(qū)別是默認(rèn)的派生訪問說明符,一個是public繼承,一個是private繼承。
轉(zhuǎn)載于:https://www.cnblogs.com/StormWendy/p/8465693.html
總結(jié)
以上是生活随笔為你收集整理的c++面向对象的程序设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么能提额浦发银行信用卡 提额技巧盘点
- 下一篇: 谈判专家(东方化改题+懒得看标程)