從零開始學C++之繼承(三):多重繼承、虛繼承與虛基類

來源:互聯網
上載者:User

一、多重繼承

單重繼承——一個衍生類別最多隻能有一個基類
多重繼承——一個衍生類別可以有多個基類

class 類名: 繼承方式 基類1,繼承方式 基類2,…. {….};

衍生類別同時繼承多個基類的成員,更好的軟體重用
可能會有大量的二義性,多個基類中可能包含同名變數或函數

多重繼承中解決訪問歧義的方法:

基類名::資料成員名(或成員函數(參數表))

明確指明要訪問定義於哪個基類中的成員


 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
using namespace std;

class Bed
{
public:
    Bed(int weight) : weight_(weight)
    {

    }
    void Sleep()
    {
        cout << "Sleep ..." << endl;
    }
    int weight_;
};

class Sofa
{
public:
    Sofa(int weight) : weight_(weight)
    {

    }
    void WatchTV()
    {
        cout << "Watch TV ..." << endl;
    }
    int weight_;
};

class SofaBed : public Bed, public Sofa
{
public:
    SofaBed() : Bed(0), Sofa(0)
    {
        FoldIn();
    }
    void FoldOut()
    {
        cout << "FoldOut ..." << endl;
    }
    void FoldIn()
    {
        cout << "FoldIn ..." << endl;
    }
};

int main(void)
{
    SofaBed sofaBed;
    //sofaBed.weight_ = 10; error
    //sofaBed.weight_ = 20; error

    sofaBed.Bed::weight_ = 10;
    sofaBed.Sofa::weight_ = 20;

    sofaBed.WatchTV();
    sofaBed.FoldOut();
    sofaBed.Sleep();

    return 0;
}

不能直接寫 sofaBed.weight_ = 10; 因為sofaBed 繼承了Sofa 和 Bed ,實際上有weigh_的兩份拷貝,這樣指向不明。只能通過

sofaBed.Bed::weight_ = 10; 訪問,但實際上一個sofaBed理應只有一個weight_,下面通過虛基類和虛繼承可以解決這個問題。


二、虛繼承與虛基類

當衍生類別從多個基類派生,而這些基類又從同一個基類派生,則在訪問此共同基類中的成員時,將產生二義性,可以採用虛基類來解決。

虛基類的引入

用於有共同基類的場合

聲明

以virtual修飾說明基類 例:class B1:virtual public BB

作用

主要用來解決多繼承時可能發生的對同一基類繼承多次而產生的二義性問題.

為最遠的衍生類別提供唯一的基類成員,而不重複產生多次拷貝


 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
using namespace std;

class Furniture
{
public:
    Furniture(int weight) : weight_(weight)
    {
        cout << "Furniture ..." << endl;
    }
    ~Furniture()
    {
        cout << "~Furniture ..." << endl;
    }
    int weight_;
};

class Bed : virtual public Furniture
{
public:
    Bed(int weight) : Furniture(weight)
    {
        cout << "Bed ..." << endl;
    }
    ~Bed()
    {
        cout << "~Bed ..." << endl;
    }
    void Sleep()
    {
        cout << "Sleep ..." << endl;
    }

};

class Sofa : virtual public Furniture
{
public:
    Sofa(int weight) : Furniture(weight)
    {
        cout << "Sofa ..." << endl;
    }
    ~Sofa()
    {
        cout << "~Sofa ..." << endl;
    }
    void WatchTV()
    {
        cout << "Watch TV ..." << endl;
    }
};

class SofaBed : public Bed, public Sofa
{
public:
    SofaBed(int weight) : Bed(weight), Sofa(weight), Furniture(weight)
    {
        cout << "SofaBed ..." << endl;
        FoldIn();
    }
    ~SofaBed()
    {
        cout << "~SofaBed ..." << endl;
    }
    void FoldOut()
    {
        cout << "FoldOut ..." << endl;
    }
    void FoldIn()
    {
        cout << "FoldIn ..." << endl;
    }
};

int main(void)
{
    SofaBed sofaBed(5);
    sofaBed.weight_ = 10;

    sofaBed.WatchTV();
    sofaBed.FoldOut();
    sofaBed.Sleep();

    return 0;
}



此時只有一份weigh_,不存在訪問歧義的問題。

從輸出可以總結出:

1、虛基類的成員是由最遠衍生類別的建構函式通過調用虛基類的建構函式進行初始化的。
2、在整個繼承結構中,直接或間接繼承虛基類的所有衍生類別,都必須在建構函式的成員初始化表中給出對虛基類的建構函式的調用。如果未列出,則表示調用該虛基類的預設建構函式。
3、在建立對象時,只有最遠衍生類別的建構函式調用虛基類的建構函式,該衍生類別的其他基類對虛基類建構函式的調用被忽略。


參考:

C++ primer 第四版
Effective C++ 3rd
C++編程規範

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.