53_被遺棄的多重繼承(上)

0. 問題:C++中是否允許一個類繼承自多個父類?

C++支持編寫多重繼承的代碼:
(1) 一個子類可以擁有多個父類
(2) 子類擁有所有父類的成員變量
(3) 子類繼承所有父類的成員函數(shù)
(4) 子類對象可以當(dāng)作任意父類對象使用

多重繼承的本質(zhì)與單繼承相同

1. 多重繼承問題一:通過多重繼承得到的對象可能擁有 “不同的地址”

編程說明:多重繼承問題一:通過多重繼承得到的對象可能擁有 “不同的地址”

#include <iostream>
#include <string>

using namespace std;

class BaseA
{
    int ma;
public:
    BaseA(int a) 
    {
        ma = a;
    }
    
    int getA()
    {
        return ma;
    }
};

class BaseB
{
    int mb;
public:
    BaseB(int b) 
    {
        mb = b;
    }
    
    int getB()
    {
        return mb;
    }
};

class Derived : public BaseA, public BaseB  // 多重繼承
{
    int mc;
public:
    Derived(int a, int b, int c) : BaseA(a) , BaseB(b)
    {
        mc = c;
    }
    
    int getC()
    {
        return mc;
    }
};

int main()
{
    Derived d(1, 2, 3);
    
    cout << d.getA() << endl;
    cout << d.getB() << endl;
    cout << d.getC() << endl;
    
    cout << endl;
    
    BaseA* pa = &d;
    BaseB* pb = &d;
    
    cout << "pa->getA() = " << pa->getA() << endl;
    cout << "pb->getB() = " << pb->getB() << endl;  
    
    cout << endl;
    
    void* ppa = pa;
    void* ppb = pb;
    
    
    if( ppa == ppb)
    {
        cout << "pa == pb" << endl;
    }
    else
    {
        cout << "pa != pb" << endl;
    }
    
    cout << "pa = " << pa << endl;
    cout << "pb = " << pb << endl;  
        
    return 0;
}

輸出結(jié)果:

1
2
3

pa->getA() = 1
pb->getB() = 2

pa != pb
pa = 0xbfd49424
pb = 0xbfd49428

總結(jié): 通過多重繼承得到的對象可能擁有不同的地址S勺馈@奥挑社!

多重繼承可能會造成同一對象地址不同

2. 多重繼承問題二:多重繼承可能產(chǎn)生冗余的成員

編程說明:多重繼承問題二:多重繼承可能產(chǎn)生冗余的成員

#include <iostream>
#include <string>

using namespace std;

class People
{
    string mName;
    int mAge;
public:
    People(string name, int age)
    {
        mName = name;
        mAge = age;
    }
    
    void print()
    {
        cout << "Name = " << mName << ", "
             << "Age = " << mAge << endl;
    }
};


class Teacher : public People
{
public:
    Teacher(string name, int age) : People(name, age)
    {
    
    }
};

class Student : public People
{
public:
    Student(string name, int age) : People(name, age)
    {
    
    }

};

class Doctor : public Teacher, public Student
{
public:
    Doctor(string name, int age) : Teacher(name, age), Student(name, age)
    {
    
    }
};

int main()
{
    Doctor d("jacob", 30);
    
//  d.print();    // error: request for member 'print()' is ambiguous
    d.Teacher::print();
    d.Student::print();

    return 0;
}

輸出結(jié)果:

Name = jacob, Age = 30
Name = jacob, Age = 30

總結(jié): 當(dāng)多重繼承關(guān)系出現(xiàn)閉合時將產(chǎn)生數(shù)據(jù)冗余的問題R绞佟!盈咳!
解決方案:虛繼承
(1) 虛繼承能夠解決數(shù)據(jù)冗余問題
(2) 中間層父類不再關(guān)心頂層父類的初始化耿眉,由子類直接初始化
(3) 最終子類必須直接調(diào)用頂層父類的構(gòu)造函數(shù)

虛繼承

編程說明:虛繼承

#include <iostream>
#include <string>

using namespace std;

class People
{
    string mName;
    int mAge;
public:
    People(string name, int age)
    {
        mName = name;
        mAge = age;
    }
    
    void print()
    {
        cout << "Name = " << mName << ", "
             << "Age = " << mAge << endl;
    }
};


class Teacher : virtual public People
{
public:
    Teacher(string name, int age) : People(name, age)
    {
    
    }
};

class Student : virtual public People
{
public:
    Student(string name, int age) : People(name, age)
    {
    
    }

};

class Doctor : public Teacher, public Student
{
public:
    Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age)
    {
    
    }
};
s
int main()
{
    Doctor d("jacob", 30);
    
    d.print();

    return 0;
}

輸出結(jié)果:

Name = jacob, Age = 30

虛繼承在技術(shù)上解決了多重繼承的冗余問題,但是在大型項目開發(fā)中鱼响,使用虛繼承時需要查找父類時是困難的鸣剪,開發(fā)的復(fù)雜性增加。
在架構(gòu)設(shè)計中丈积,需要繼承時筐骇,無法確定使用直接繼承還是虛繼承
在工程項目開發(fā)中江滨,不使用多重繼承

3. 小結(jié)

  • C++支持多重繼承的編程方式
  • 多重繼承容易帶來問題
    (1) 可能出現(xiàn)同一個對象的地址不同的情況
    (2) 虛繼承可以解決數(shù)據(jù)冗余的問題
    (3) 虛繼承的使得架構(gòu)師設(shè)計可能出現(xiàn)問題
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拥褂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子牙寞,更是在濱河造成了極大的恐慌饺鹃,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间雀,死亡現(xiàn)場離奇詭異悔详,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惹挟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門茄螃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人连锯,你說我怎么就攤上這事归苍。” “怎么了运怖?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵拼弃,是天一觀的道長褪尝。 經(jīng)常有香客問我件缸,道長,這世上最難降的妖魔是什么融欧? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任咏连,我火速辦了婚禮盯孙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祟滴。我一直安慰自己振惰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布垄懂。 她就那樣靜靜地躺著骑晶,像睡著了一般痛垛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上透罢,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天榜晦,我揣著相機(jī)與錄音冠蒋,去河邊找鬼羽圃。 笑死,一個胖子當(dāng)著我的面吹牛抖剿,可吹牛的內(nèi)容都是我干的朽寞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼斩郎,長吁一口氣:“原來是場噩夢啊……” “哼脑融!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缩宜,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肘迎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锻煌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妓布,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年宋梧,在試婚紗的時候發(fā)現(xiàn)自己被綠了匣沼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡捂龄,死狀恐怖释涛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倦沧,我是刑警寧澤唇撬,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站展融,受9級特大地震影響局荚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜愈污,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一耀态、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧暂雹,春花似錦首装、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驰吓。三九已至,卻和暖如春系奉,著一層夾襖步出監(jiān)牢的瞬間檬贰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工缺亮, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留翁涤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓萌踱,卻偏偏與公主長得像葵礼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子并鸵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359