chapter-15

// chapter-15.cpp : 繼承和動態(tài)綁定误辑!
//

#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
#include<memory>

using namespace std;

class Quote         //報價,基類.
{
public:
    Quote() = default;
    Quote(const string &book,double sales_price):bookNo(book),price(sales_price){}
    string isbn() const { return bookNo; }
    virtual double net_price(size_t n) const { return n*price; }//虛函數(shù)斩披,希望派生類重定義覆蓋创南!當使用指針或引用調用函數(shù)時,將發(fā)生動態(tài)綁定!
    virtual ~Quote() = default;                     //繼承中,根類通常應該定義一個虛析構函數(shù)!來保證使用正確的析構函數(shù)釋放對象!
private:    
    string bookNo;
protected:                                          //派生類可以訪問共有成員霹期,保護成員,不能訪問私有成員拯田。類外只能訪問共有成員历造!
    double price = 0.0;
};

class Bulk_Quote:public Quote
{
public:
    Bulk_Quote() = default;     //每個類負責定義各自的接口,想要與類的對象交互必須使用該類的結構船庇。即是派生類初始化時吭产,也必須使用基類的構造函數(shù)來初始化那些從基類中繼承而來的成員!
    Bulk_Quote(const string &book, double sales_price, size_t mq, double ds) :Quote(book,sales_price), min_qty(mq), discount(ds) {}
    double net_price(size_t n) const override     //override表示覆蓋基類中虛函數(shù)鸭轮,如果沒覆蓋則引發(fā)錯誤臣淤!
    {
        if (n >= min_qty)
            return n*(1 - discount)*price;
        else
        {
            return n*price;
        }
    }
private:
    size_t min_qty = 0;
    double discount = 0.0;
};

class Disc_Quote:public Quote
{
public:
    Disc_Quote() = default;
    Disc_Quote(const string &book,double price,size_t qty,double disc):Quote(book,price),quantity(qty),discount(disc){}
    double net_price(size_t n) const = 0;       //含有純虛函數(shù)的類為抽象基類,后續(xù)其他類可以覆蓋接口窃爷,但是不能創(chuàng)建抽象基類的對象邑蒋!
protected:
    size_t quantity = 0;
    double discount = 0;
};
class Bulk_DiscQuote:public Disc_Quote
{
public:
    Bulk_DiscQuote() = default;
    Bulk_DiscQuote(const string &book, double price, size_t qty, double disc) :Disc_Quote(book, price, qty, disc) {}
    double net_price(size_t n) const override;
};
double Bulk_DiscQuote::net_price(size_t n) const
{
    if (n >= quantity)
        return n*(1 - discount)*price;
    else
    {
        return n*price;
    }
}

class Base
{
public:
    size_t size()const { return n; }
private:
    size_t n;
};
class Pri_Base:public Base
{
public:
    using Base::size;           //通過using聲明,改變成員的可訪問性按厘!
private:
    //using Base::n;
};


int main()
{

    //根部為基類医吊,從基類繼承的為派生類〈基類負責定義層次關系中所有類共同擁有的成員卿堂,而派生類定義各自特有的成員!
    //在基類中聲明函數(shù)造虏,在各自派生類中定義適合自身的版本御吞,此時基類就將這些函數(shù)聲明為虛函數(shù)!在運行中漓藕,實際執(zhí)行的虛函數(shù)版本將由派生類對象而定,即為動態(tài)綁定挟裂!
    Quote qb1("c++", 150);
    Bulk_Quote qb2("c++", 150,1,0.2);
    Quote *p = &qb2;
    Quote &r = qb2;                             //p和r分別指向qb2的Quote部分(派生類向基類轉換只針對指針(包括智能指針)和引用享钞,基類向派生類不存在隱式類型轉換,根據(jù)派生類繼承方式而受影響诀蓉!(1栗竖、公有繼承!544頁)(基類派生類之間不存在對象轉換渠啤,多余部分會被切除:)
    cout << qb1.net_price(4) << " " << qb2.net_price(4) << endl;    //動態(tài)綁定!

    //如果基類中定義了靜態(tài)成員沥曹,則所有繼承體系中只存在該成員唯一定義份名!如果static為private碟联,則派生類無權訪問它!
    //派生類聲明時僵腺,不需要派生類表(基類名稱)鲤孵,聲明形式class Bulk_Quote;辰如、普监、如果某類為基類,則必須在之前已經聲明且定義琉兜、凯正、為了防止類被繼承,則可以補充聲明:class Quote final;
    //可以對函數(shù)聲明final豌蟋,則繼承類所有嘗試覆蓋操作都是錯誤的漆际!可以對函數(shù)聲明override,顯示為對基類虛函數(shù)的重定義夺饲!

    //抽象基類奸汇,對Quote進行重構,以便將操作和數(shù)據(jù)移向Bulk_DiscQuote(DiscQuote為抽象基類無法創(chuàng)建對象M)
    Bulk_DiscQuote bdq1("c++", 150, 1, 0.2);
    cout << bdq1.net_price(4) << endl;

    //類成員public擂找、protected、private分別控制繼承類是否可以訪問浩销;公有贯涎、私有、受保護繼承分別控制派生類對基類成員的訪問權限(更改公有和保護屬性的屬性值B蟆)
    //基類應該將接口聲明為公有塘雳,將派生類訪問聲明為保護,將基類和友元訪問成員聲明為私有普筹!
    //友元關系不能繼承败明!不能傳遞!(對于派生類的友元太防,可以通過派生類對象訪問基類成員妻顶!543!對于基類的友元蜒车,可以訪問基類成員和派生類的基類部分;渲觥)

    //在繼承作用域內,派生類如果定義了相同成員(同類型酿愧、形參)可以覆蓋基類成員沥潭。查找的順序由派生類到基類。而對于指針引用來說嬉挡,根據(jù)其聲明的類型決定查找的開始范圍钝鸽!
    //如果派生類需要使用基類中的重載函數(shù)汇恤,建議使用Using fun聲明!避免在派生類中定義了同名函數(shù)寞埠,而導致覆蓋Fㄖ谩(作用域內,除了虛函數(shù)仁连,應避免重定義基類中存在的成員對象)

    //基類和派生類如需要拷貝移動賦值蓝角,則需要各自定義!(基類必須定義虛析構函數(shù)7苟)
    //容器與繼承使鹅,使用智能指針,避免派生類成員被丟棄昌抠!
    vector<shared_ptr<Quote>> basket;
    basket.push_back(make_shared<Quote>("c++", 150));//參數(shù)不同體現(xiàn)了患朱,每個類各自負責自己的初始化!(利用構造函數(shù)初始化4渡弧)
    basket.push_back(make_shared<Bulk_DiscQuote>("html", 150, 1, 0.2));
    cout << basket.back()->net_price(4) << endl;

    system("pause");
    return 0;
}

//面向對象程序設計基于3個基本概念:數(shù)據(jù)抽象裁厅、繼承和動態(tài)綁定!
//可以將基類的引用和指針綁定在派生類對象上侨艾,這是c++面向對象編程的關鍵所在执虹!而派生類對象實質是不能向基類轉換,當發(fā)生時唠梨,派生類非繼承成員將被切掉袋励!
//基類和派生類的虛函數(shù)默認實參最好一致!
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末当叭,一起剝皮案震驚了整個濱河市茬故,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚁鳖,老刑警劉巖磺芭,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異才睹,居然都是意外死亡徘跪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門琅攘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人松邪,你說我怎么就攤上這事坞琴。” “怎么了逗抑?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵剧辐,是天一觀的道長寒亥。 經常有香客問我,道長荧关,這世上最難降的妖魔是什么溉奕? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮忍啤,結果婚禮上加勤,老公的妹妹穿的比我還像新娘。我一直安慰自己同波,他們只是感情好鳄梅,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著未檩,像睡著了一般戴尸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冤狡,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天孙蒙,我揣著相機與錄音,去河邊找鬼悲雳。 笑死挎峦,一個胖子當著我的面吹牛,可吹牛的內容都是我干的怜奖。 我是一名探鬼主播浑测,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歪玲!你這毒婦竟也來了迁央?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤滥崩,失蹤者是張志新(化名)和其女友劉穎岖圈,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钙皮,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡蜂科,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了短条。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滩届。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖依疼,靈堂內的尸體忽然破棺而出晶伦,到底是詐尸還是另有隱情,我是刑警寧澤可都,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布缓待,位于F島的核電站蚓耽,受9級特大地震影響,放射性物質發(fā)生泄漏旋炒。R本人自食惡果不足惜步悠,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘫镇。 院中可真熱鬧鼎兽,春花似錦、人聲如沸汇四。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽通孽。三九已至序宦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間背苦,已是汗流浹背互捌。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留行剂,地道東北人秕噪。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像厚宰,于是被迫代替她去往敵國和親腌巾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容