C++基礎(chǔ)-(繼承)

C++ 基礎(chǔ)

概念及工方式

  1. 保持已有類的特性而構(gòu)造新類的過(guò)程稱為繼承铁坎。
  2. 在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過(guò)程稱為派生访忿。
  3. 被繼承的已有類稱為基類(或父類)。
  4. 派生出的新類稱為派生類(或子類)

繼承的目的

  • 實(shí)現(xiàn)代碼重用
  • 派生的目的:當(dāng)新的問(wèn)題出現(xiàn),原有程序無(wú)法解決(或不能完全解決)時(shí)痴荐,需要對(duì)原有程序進(jìn)行改造

派生類的構(gòu)造

  1. 派生類可以直接訪問(wèn)基類的保護(hù)數(shù)據(jù)成員
  2. 只以接口作溝通。即使基類與子類也不例外官册。這正是類能夠發(fā)揮其生命力的原因所在生兆。
  3. 在構(gòu)造一個(gè)子類時(shí),完成其基類部分的構(gòu)造由基類的構(gòu)造函數(shù)去做

繼承的訪問(wèn)權(quán)限

  • 不同繼承方式的影響主要體現(xiàn)在:
  1. 派生類成員對(duì)基類成員的訪問(wèn)權(quán)限
  2. 通過(guò)派生類對(duì)象對(duì)基類成員的訪問(wèn)權(quán)限
  • 三種繼承方式
  1. 公有繼承
  2. 私有繼承
  3. 保護(hù)繼承

公有繼承

  1. 基類的public和protected成員的訪問(wèn)屬性在派生類中保持不變,但基類的private成員不可直接訪問(wèn)膝宁。
  2. 派生類中的成員函數(shù)可以直接訪問(wèn)基類中的public和protected成員鸦难,但不能直接訪問(wèn)基類的private成員。
  3. 通過(guò)派生類的對(duì)象只能訪問(wèn)基類的public成員员淫。

私有繼承

  1. 基類的public和protected成員都以private身份出現(xiàn)在派生類中合蔽,但基類的private成員不可直接訪問(wèn)。
  2. 派生類中的成員函數(shù)可以直接訪問(wèn)基類中的public和protected成員介返,但不能直接訪問(wèn)基類的private成員拴事。
  3. 通過(guò)派生類的對(duì)象不能直接訪問(wèn)基類中的任何成員沃斤。

保護(hù)繼承

  1. 基類的public和protected成員都以protected身份出現(xiàn)在派生類中,但基類的private成員不可直接訪問(wèn)挤聘。
  2. 派生類中的成員函數(shù)可以直接訪問(wèn)基類中的public和protected成員轰枝,但不能直接訪問(wèn)基類的private成員。
  3. 通過(guò)派生類的對(duì)象不能直接訪問(wèn)基類中的任何成員

默認(rèn)的繼承是私有

private 和protect的區(qū)別

  1. 在單個(gè)類中组去,protected和private沒(méi)有什么區(qū)別鞍陨。
  2. 但在繼承關(guān)系中,基類的private成員不但對(duì)應(yīng)用程序隱藏从隆,
  3. 甚至對(duì)派生類也隱藏诚撵。而基類的保護(hù)成員則只對(duì)應(yīng)用程序隱藏,而對(duì)派生類則毫不隱瞞键闺。

繼承

  • 繼承
    • 抽出共性寿烟,重新分配,代碼可重用
    • 繼承可以使我們用一種簡(jiǎn)單的方式來(lái)描述事物
#include <iostream>
using namespace std;
class Shop
{
    public:
        int m_a;
        void sailDailyGoods()
        {
            cout<<"賣(mài)日用品"<<endl;
            return;
        }
};
class Market:public Shop
{
    public:
        void saleFood()
        {
            m_a=110;
            cout<<"賣(mài)食物"<<endl;
            return;
        }
};
class SuperMarket:public Market
{
    public:
        void pay()
        {
            cout<<"代繳水電費(fèi)"<<endl;
            return;
        }
};
int main(int argc,char**argv)
{
    SuperMarket sm;
    sm.sailDailyGoods();
    sm.saleFood();
    sm.pay();
    
}
  • 三種繼承方式
    • 公有繼承
    • 私有繼承
    • 保護(hù)繼承
  • 派生類可以直接訪問(wèn)
#include <iostream>
using namespace std;
class shop
{
    int m_a;
    public:
        shop(int a/*=110*/)
        {
            m_a=a;
            cout<<"shop construct"<<m_a<<endl;
        }
        ~shop()
        {
            cout<<"析構(gòu)shop"<<endl;
        }
        /*
        shop()
        {
            m_a=333;
        }*/
};
class test
{
    public:
        test()
        {
            cout<<"test construct"<<endl;
        }
        ~test()
        {
            cout<<"析構(gòu)test"<<endl;
        }
};
class Market:public shop//繼承重用代碼
{
    test m_t;
    public:
        Market():shop(120)
        {
            cout<<"Market construct"<<endl;
        }
        ~Market()
        {
            cout<<"析構(gòu)Market"<<endl;
        }
};
int main(int argc,char**argv)
{
    Market m;
    cout<<"===="<<endl;
}
//shop construct120
//test construct
//Market construct
//====
//析構(gòu)Market
//析構(gòu)test
//析構(gòu)shop

#include<iostream>
using namespace std;
class Shop
{
protected:
    int m_a;
public:
    void saleDaliyGoods()
    {
        cout<<"賣(mài)日用品"<<endl;
        return;
    }
};
class Market:public Shop
{
public:
    void saleFood()
    {
        m_a=10;
        cout<<"食品"<<m_a<<endl;
        return;
    }
};
int main(int argc,char **argv)
{
    Market m;
//  m.m_a=10;
    m.saleDaliyGoods();
    m.saleFood();
}
//用protected ,則在Market中可以訪問(wèn),但是在int main中,m.m_a=10;是錯(cuò)誤的

#include<iostream>
using namespace std;
class Shop
{
public:
    Shop()
    {
        cout<<"Shop construct"<<endl;
    }
};
class Market:public Shop
{
public:
    Market()
    {
        cout<<"Market construct"<<endl;
    }
};
int main()
{
    Market m;
}
//結(jié)果為:
//shop construct
//Market construct

#include<iostream>
using namespace std;
class Shop
{
    int m_a;
public:
    Shop(int a)
    {
        m_a=a;
        cout<<"Shop construct"<<m_a<<endl;
    }
};
class Market:public Shop
{
public:
    Market():Shop(222)
    {
        cout<<"Market construct"<<endl;
    }
};
int main()
{
    Market m;
}
//結(jié)果為:
//Shop construct222
//Market construct

#include<iostream>
using namespace std;
class Shop
{
    int m_a;
public:
    Shop(int a=111)
    {
        m_a=a;
        cout<<"Shop construct"<<m_a<<endl;
    }

};
class Market:public Shop
{
    
public:
    Market():Shop()
    {
        cout<<"Market construct"<<endl;
    }
    
};
int main()
{
    Market m;
}
//結(jié)果為:Shop construct111
//Market construct

#include<iostream>
using namespace std;
class Shop
{
    int m_a;
public:
    Shop(int a)
    {
        m_a=a;
        cout<<"Shop construct"<<m_a<<endl;
    }
    Shop()
    {
        m_a=333;
        cout<<"Shop construct"<<m_a<<endl;
    }
};
class Market:public Shop
{
    
public:
    Market():Shop()
    {
        cout<<"Market construct"<<endl;
    }
    
};
int main()
{
    Market m;
}
//結(jié)果為:
Shop construct333
//Market construct

賦值兼容規(guī)則

  • 賦值兼容規(guī)則中所指的替代包括以下的情況:
  1. 派生類的對(duì)象可以賦值給基類對(duì)象辛燥。
  2. 派生類的對(duì)象可以初始化基類的引用筛武。
  3. 派生類對(duì)象的地址可以賦給指向基類的指針。

重寫(xiě)虛函數(shù),實(shí)現(xiàn)多態(tài)(多態(tài))

  • 多態(tài)是C++的重要概念,是面向?qū)ο笤O(shè)計(jì)理念的精華, 大型的C++軟件項(xiàng)目和大型的系統(tǒng)實(shí)現(xiàn)中,多態(tài)是必不可少的,可以減輕系統(tǒng)升級(jí)挎塌、維護(hù)徘六、調(diào)試的工作量和復(fù)雜度.

多態(tài)的條件

  1. C++多態(tài)是通過(guò)虛函數(shù)實(shí)現(xiàn)的,虛函數(shù)允許子類重新定義成員函數(shù)榴都,而子類重新定義父類接口的做法稱為覆蓋或重寫(xiě)
  2. 子類需要公有繼承于父類
  3. 定義父類的指針或引用待锈,然后通過(guò)指針或引用去調(diào)用相應(yīng)的虛函數(shù)

虛函數(shù)

  1. 成員函數(shù)之前加上 virtua
    關(guān)鍵字之后,就是虛成員函數(shù)

判斷子類的成員函數(shù)是否為虛函數(shù)

  1. 該函數(shù)是否與基類的虛函
    數(shù)相同的函數(shù)名
  2. 該函數(shù)是否與基類的虛函數(shù)有相同的參數(shù)個(gè)數(shù)及相同的對(duì)應(yīng)參數(shù)類型
  3. 該函數(shù)是否與基類的虛函數(shù)有相同的返回值或者滿足賦值兼容規(guī)則的指針嘴高、引用的返回值

多態(tài)與非多態(tài)的區(qū)別

  • 多態(tài)與非多態(tài)的區(qū)別就是函數(shù)地址是早綁定還是晚綁定竿音。如果函數(shù)的調(diào)用在編譯期間就可以確定函數(shù)的調(diào)用地址,并生產(chǎn)代碼拴驮,就是靜態(tài)的也就是早綁定是非多態(tài)的春瞬。而如果函數(shù)的調(diào)用地址不能在編譯期間確定,需要在運(yùn)行時(shí)才確定套啤,這就是晚綁定也稱動(dòng)態(tài)聯(lián)編宽气,是多態(tài)的
#include <iostream>
using namespace std;
class B0
{
    public:
        virtual void display()
        {
            cout<<"B0 Display"<<endl;
        }
};
class B1:public B0
{   
    public:
        void display()
        {
            cout<<"B1 Display"<<endl;
        }
};
class B2:public B1
{   
    public:
        void display()
        {
            cout<<"B2 Display"<<endl;
        }
};
int main()
{
/*
    B0 b0;b0.display();
    B1 b1;b1.display();
    B2 b2;b2.display();
    B2 b3;b3.B1::display();*/
    B0 b0,*p0;
    p0=&b0;
    p0->display();
    B1 b1;
    p0=&b1;//一個(gè)函數(shù)表現(xiàn)出不同的形態(tài)
    p0->display();
    B2 b2;
    p0=&b2;
    p0->display();
}

重載與重寫(xiě)的區(qū)別(重寫(xiě)重要)

  1. 重載overload:函數(shù)名相同,參數(shù)列表不同纲岭,重載只是在同類的內(nèi)部存在,并且不能靠返回值來(lái)判斷
  2. 重寫(xiě)overwrite:也稱覆蓋线罕,子類重新定義父類中的同名函數(shù)止潮。函數(shù)特征相同,單數(shù)具體實(shí)現(xiàn)不同钞楼,基類的函數(shù)要有關(guān)鍵字virtual,主要是在繼承關(guān)系中出現(xiàn)喇闸。
  • 多態(tài)實(shí)現(xiàn)原理
    • 每個(gè)含有虛函數(shù)的類,編譯器都會(huì)為他自動(dòng)生成一個(gè)虛表,表中每一個(gè)元素都是指向虛函數(shù)的地址燃乍。
    • 虛指針:編譯器會(huì)為含有虛函數(shù)的類增加一個(gè)成員唆樊,是指向該虛函數(shù)的指針,每一個(gè)由此的派生出來(lái)的類都活有一個(gè)虛指針刻蟹。
  • 函數(shù)的調(diào)用地址在編譯期間就能決定逗旁,那就是非多態(tài)。如果在運(yùn)行時(shí)才能確定舆瘪,就是多態(tài)的片效。
  • 繼承為了實(shí)現(xiàn)代碼重用。
  • 多態(tài)為了實(shí)現(xiàn)接口重用英古。
#include <iostream>
using namespace std;
/*class B0
{
    public:
        virtual void display()
        {
            cout<<"B0 Display"<<endl;
        }
};
class B1:public B0
{   
    public:*/
    /*  void display()
        {
            cout<<"B1 Display"<<endl;
        }*/
/*};

int main()
{*/
/*
    B0 b0;b0.display();
    B1 b1;b1.display();
    B2 b2;b2.display();
    B2 b3;b3.B1::display();*/
/*  B0 b0,*p0;
    p0=&b0;
    p0->display();
    B1 b1;
    p0=&b1;//一個(gè)函數(shù)表現(xiàn)出不同的形態(tài)
    p0->display();
    
}*/
class B0
{
    public:
        virtual void display()=0;//純虛函數(shù)
};
class B1:public B0
{   
    public:
        void display()
        {
            cout<<"B1 Display"<<endl;
        }
};

int main()
{
/*
    B0 b0;b0.display();
    B1 b1;b1.display();
    B2 b2;b2.display();
    B2 b3;b3.B1::display();*/
    B0 *p0;
    B1 b1;
    p0=&b1;//一個(gè)函數(shù)表現(xiàn)出不同的形態(tài)
    p0->display();
}
//B1 Display
  • 共態(tài)的使用
#include <iostream>
using namespace std;
class person
{
    public:
        int id;
};
class A:virtual public person
{
    public:
        void performForA()
        {
            cout<<"呆,傻,逗,癡"<<endl;
        }
};
class B:virtual public person
{
    public:
        void performForB()
        {
            cout<<"浪,騷,蕩,賤"<<endl;
        }
};
class sb:public A,public B
{
};
int main()
{
        sb jxb;
        jxb.performForA();
        jxb.performForB();      
        jxb.id=3;
        person *p=&jxb;
}

繼承順序

  1. 任何虛擬基類的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造
  2. 任何非虛擬基類的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造淀衣;
  3. 任何成員對(duì)象的構(gòu)造函數(shù)按照它們聲明的順序調(diào)用;
    類自己的構(gòu)造函數(shù)召调。
  • 如果兩個(gè)父類膨桥。。唠叛。只嚣。。玻墅。介牙。。澳厢。环础。。剩拢。线得。。徐伐。贯钩。
#include <iostream>
using namespace std;
class A
{
    public:
        A()
        {
            cout<<"A construct"<<endl;
        }
        ~A()
        {
            cout<<"析構(gòu)A"<<endl;
        }
};
class B
{
    public:
        B()
        {
            cout<<"B construct"<<endl;
        }
        ~B()
        {
            cout<<"析構(gòu)B"<<endl;
        }
};
class C
{
    public:
        C()
        {
            cout<<"C construct"<<endl;
        }
        ~C()
        {
            cout<<"析構(gòu)C"<<endl;
        }
};
class D:public A,public B,virtual public C
{
    public:
        D()
        {
            cout<<"D construct"<<endl;
        }
        ~D()
        {
            cout<<"析構(gòu)D"<<endl;
        }
};
int main()
{
    D d;
}/*
C construct
A construct
B construct
D construct
析構(gòu)D
析構(gòu)B
析構(gòu)A
析構(gòu)C*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市办素,隨后出現(xiàn)的幾起案子角雷,更是在濱河造成了極大的恐慌,老刑警劉巖性穿,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勺三,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡需曾,警方通過(guò)查閱死者的電腦和手機(jī)吗坚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)祈远,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人商源,你說(shuō)我怎么就攤上這事车份。” “怎么了牡彻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵扫沼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我讨便,道長(zhǎng)充甚,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任霸褒,我火速辦了婚禮伴找,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘废菱。我一直安慰自己技矮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布殊轴。 她就那樣靜靜地躺著衰倦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旁理。 梳的紋絲不亂的頭發(fā)上樊零,一...
    開(kāi)封第一講書(shū)人閱讀 51,610評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音孽文,去河邊找鬼驻襟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛芋哭,可吹牛的內(nèi)容都是我干的沉衣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼减牺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼豌习!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拔疚,我...
    開(kāi)封第一講書(shū)人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肥隆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后稚失,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體栋艳,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年墩虹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘱巾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诫钓,死狀恐怖旬昭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菌湃,我是刑警寧澤问拘,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站惧所,受9級(jí)特大地震影響骤坐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜下愈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一纽绍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧势似,春花似錦拌夏、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至栅迄,卻和暖如春站故,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背毅舆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工西篓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朗兵。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓污淋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親余掖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寸爆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容