国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

面向?qū)ο蟪绦蛟O(shè)計(jì)之基類,派生類與虛函數(shù)

2019-11-11 05:34:30
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

面向?qū)ο蟪绦蛟O(shè)計(jì)的核心思想是:

數(shù)據(jù)抽象:實(shí)現(xiàn)類與接口的分離。

繼承:定義相似類型并進(jìn)行相似關(guān)系建模。通過(guò)繼承聯(lián)系在一起的類構(gòu)成一種層次關(guān)系。通常在在層次關(guān)系的根部有一個(gè)基類,其他類直接或間接由基類繼承而來(lái)。這些繼承的類稱為派生類基類負(fù)責(zé)定義在層次關(guān)系中所有類共同擁有的成員,而每個(gè)派生類定義各自特有的成員。對(duì)于某些函數(shù),基類希望它的派生類各自定義適合自身的版本,此時(shí)的基類就將這些函數(shù)聲明成虛函數(shù)

class Quote{public: std::string isbn() const; virtual double net_PRice(std::size_t n) const;};

派生類必須使用派生列表,必須將其繼承而來(lái)的成員函數(shù)中需要覆蓋的那些重新聲明:

class Bulk_Quote : public Quote//Bulj_Quote繼承了Quote{ double net_price(std::size_t n) const override;};

動(dòng)態(tài)綁定:一定程序忽略相似類型的區(qū)別,而以統(tǒng)一的方式使用他們的對(duì)象。 在C++語(yǔ)言中,當(dāng)我們使用基類引用或指針調(diào)用一個(gè)虛函數(shù)將發(fā)生動(dòng)態(tài)綁定。

double print_total(ostream &os, const A &item,size_t n){ double ret=item.net_price(n);//根據(jù)傳入的item的對(duì)象類型調(diào)用Quote::net_price,還是Bulk_Quote::net_price return ret;}

一個(gè)派生類對(duì)象包含多個(gè)組成部分:一個(gè)含有派生類自己定義的(非靜態(tài))成員的子對(duì)象,以及一個(gè)與該派生類繼承的基類的子對(duì)象。因?yàn)樵谂缮悓?duì)象中含有與其基類對(duì)應(yīng)的組成部分,所以我們能把派生類的對(duì)象當(dāng)成基類對(duì)象來(lái)使用,而且我們也能把基類的指針或引用綁定到派生類對(duì)象中的基類部分上。

Quote item;//基類對(duì)象Bulk_Quote bulk;//派生類對(duì)象Quote *p=&item;//p指向基類對(duì)象p=&bulk;//p指向派生類對(duì)象的基類部分Quote &r=bulk;//r綁定到派生類對(duì)象的基類部分

Quote類的定義:

這里寫(xiě)圖片描述

派生類Bulk_Quote定義;

這里寫(xiě)圖片描述

派生類對(duì)象的基類部分與派生類對(duì)象自己的數(shù)據(jù)成員都是在構(gòu)造函數(shù)的初始化階段執(zhí)行初始化操作的。派生類構(gòu)造函數(shù)同樣是通過(guò)構(gòu)造函數(shù)初始化列表來(lái)將實(shí)參傳遞給基類構(gòu)造函數(shù)的。

這里寫(xiě)圖片描述 每個(gè)類負(fù)責(zé)定義各自的接口。要想與類的對(duì)象交互必須使用類的接口,即使這個(gè)對(duì)象是派生類的基類部分也如此。盡管從語(yǔ)法上我們可以在派生類構(gòu)造函數(shù)體內(nèi)給它的 公有成員或受保護(hù)的基類成員賦值,但不建議這么做。


如果基類定義了一個(gè)靜態(tài)成員,則在整個(gè)繼承體系中只存在該成員的唯一定義。如果基類中的成員是private的,則派生類無(wú)權(quán)訪問(wèn)它。如果某靜態(tài)成員是可訪問(wèn)的,則我們既能通過(guò)基類使用它也能通過(guò)派生類使用它。


派生類的聲明:

class Bulk_Quote::public Quote;//錯(cuò)誤,不需要派生列表class Bulk_ Quote;//正確

如果我們想將某個(gè)類作為基類,則該類必須是已經(jīng)定義而非僅聲明。

class Quote;//聲明未定義class Bulk_Quote:public Quote{};//錯(cuò)誤

防止繼承的發(fā)生: C++11標(biāo)準(zhǔn)提供了一種防止繼承發(fā)生的方法,即在類名后跟一個(gè)關(guān)鍵字final.

這里寫(xiě)圖片描述


靜態(tài)類型與動(dòng)態(tài)類型: 表達(dá)式的靜態(tài)類型在編譯時(shí)總是已知的,它是變量聲明時(shí)的類型或表達(dá)式生成的類型。動(dòng)態(tài)類型則是變量或表達(dá)式表示的內(nèi)存的對(duì)象的類型。動(dòng)態(tài)類型直到運(yùn)行時(shí)才知道。基類的指針或引用的靜態(tài)類型可能與其動(dòng)態(tài)類型不一致,取決于傳遞的實(shí)參。


因?yàn)橐粋€(gè)基類的對(duì)象可能是派生類對(duì)象的一部分,也可能不是,所以不存在基類向派生類的自動(dòng)類型轉(zhuǎn)換即使一個(gè)基類指針或引用綁定在一個(gè)派生類對(duì)象上,我們也不能執(zhí)行從基類向派生類的轉(zhuǎn)換。

當(dāng)我們用一個(gè)派生類對(duì)象為一個(gè)基類對(duì)象初始化或者賦值時(shí),只有該派生類對(duì)象的基類部分會(huì)被拷貝、移動(dòng)或賦值,它的派生類部分被忽略掉。

Bulk_Quote bulk;//派生類對(duì)象Quote item(bulk);//調(diào)用Quote::Quote(const Quote&)item=bulk;//調(diào)用Quote::Operator=(const Quote&)

虛函數(shù): 當(dāng)我們使用基類引用或指針調(diào)用一個(gè)虛成員函數(shù)時(shí)會(huì)執(zhí)行動(dòng)態(tài)綁定。因?yàn)槲覀冎钡竭\(yùn)行時(shí)才能知道到底調(diào)用了哪個(gè)版本的虛函數(shù),所以所有虛函數(shù)必須有定義。

基類中的虛函數(shù)在派生類中隱含地也是一個(gè)虛函數(shù)。當(dāng)派生類覆蓋了某個(gè)虛函數(shù)時(shí),該函數(shù)在基類中的形參必須與派生類中的形參嚴(yán)格匹配

override說(shuō)明符說(shuō)明派生類中的虛函數(shù),final說(shuō)明之后任何嘗試覆蓋該函數(shù)的操作都將引發(fā)錯(cuò)誤。

如果我們通過(guò)基類的引用或指針調(diào)用函數(shù),則使用基類中定義的默認(rèn)實(shí)參,即使實(shí)際運(yùn)行的是派生類的函數(shù)版本也是如此即傳入派生類函數(shù)的是基類函數(shù)定義的默認(rèn)實(shí)參。如果虛函數(shù)使用默認(rèn)實(shí)參,則基類和派生類中定義的默認(rèn)實(shí)參最好一致。

#include <iostream>class A{public: A(int v):v(v){}//A構(gòu)造函數(shù) virtual void print(int x=100)//基類虛函數(shù)默認(rèn)實(shí)參 { std::cout<<x<<std::endl; }private: int v;};class B:public A//派生類 {public: B(int v):A(v){}//B構(gòu)造函數(shù) void print(int x=10) override//默認(rèn)實(shí)參與基類不一致 { std::cout<<x+100<<std::endl;//傳入基類虛函數(shù)的默認(rèn)實(shí)參 }private: };int main(){ B b(10); A &aptr=b; aptr.print();//200 return 0;}

如果我們希望對(duì)虛函數(shù)的調(diào)用不要進(jìn)行動(dòng)態(tài)綁定,而是強(qiáng)迫其執(zhí)行虛函數(shù)的某個(gè)特定版本,可以使用作用域運(yùn)算符。

//強(qiáng)行調(diào)用基類中定義的函數(shù)版本。double undiscounted=baseP->Quote::net_price(42);

如果一個(gè)派生類虛函數(shù)需要調(diào)用它的基類版本,但是沒(méi)有使用作用域運(yùn)算符,則在運(yùn)行時(shí)該調(diào)用將被解析為對(duì)派生類版本自身的調(diào)用,從而導(dǎo)致無(wú)限遞歸。


抽象基類:

我們可以在函數(shù)體的位置書(shū)寫(xiě)=0來(lái)說(shuō)明一個(gè)虛函數(shù)為純虛函數(shù)=0只能出現(xiàn)在類內(nèi)部的虛函數(shù)聲明語(yǔ)句處。我們可以為純虛函數(shù)提供定義,不過(guò)函數(shù)體必須定義在類外

double net_price(std::size_t)const=0;//純虛函數(shù)

含有(未經(jīng)覆蓋直接繼承)純虛函數(shù)的類是抽象基類。抽象基類負(fù)責(zé)定義接口,而后續(xù)的其他類可以覆蓋該接口。我們不能直接創(chuàng)建一個(gè)抽象基類的對(duì)象這里寫(xiě)圖片描述



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 定州市| 辽阳市| 光泽县| 裕民县| 玉门市| 灌阳县| 南靖县| 连山| 班玛县| 喀喇| 抚顺市| 溧水县| 南雄市| 罗源县| 射洪县| 洛川县| 建阳市| 宜川县| 德令哈市| 淅川县| 北流市| 清水河县| 白城市| 肃北| 冷水江市| 慈溪市| 蒲江县| 建平县| 洞口县| 共和县| 岳西县| 蓝山县| 红安县| 新龙县| 麻栗坡县| 湄潭县| 噶尔县| 雷波县| 顺义区| 玉林市| 凤城市|