最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++中多重繼承與虛繼承的實現(xiàn)

 更新時間:2026年03月27日 10:15:46   作者:Ralph_Y  
本文介紹了C++中的多重繼承和虛繼承機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、多重繼承(Multiple Inheritance)

1. 基本概念

多重繼承是指一個派生類同時繼承多個基類,允許派生類復用多個基類的屬性和方法,是C++區(qū)別于Java等語言的重要特性之一。

語法格式

class 派生類名 : 繼承方式1 基類1, 繼承方式2 基類2, ... {
    // 派生類成員
};
  • 繼承方式:public/protected/private(和單繼承規(guī)則一致);
  • 核心價值:讓一個類同時擁有多個類的特性(比如“汽車”同時繼承“交通工具”和“機械產(chǎn)品”)。

2. 簡單示例(無沖突的多重繼承)

#include <iostream>
using namespace std;

// 基類1:飛行動物
class Flyable {
public:
    void fly() {
        cout << "能飛" << endl;
    }
};

// 基類2:游泳動物
class Swimmable {
public:
    void swim() {
        cout << "能游泳" << endl;
    }
};

// 派生類:鴨子(同時繼承飛行動物和游泳動物)
class Duck : public Flyable, public Swimmable {
public:
    void quack() {
        cout << "嘎嘎叫" << endl;
    }
};

int main() {
    Duck duck;
    duck.fly();   // 繼承自Flyable
    duck.swim();  // 繼承自Swimmable
    duck.quack(); // 自身方法
    return 0;
}

輸出

能飛
能游泳
嘎嘎叫

這個示例中,Duck同時復用了FlyableSwimmable的方法,無任何沖突,是多重繼承的理想場景。

3. 多重繼承的核心問題:菱形繼承(鉆石繼承)

當多個基類繼承自同一個“共同基類”,而派生類又同時繼承這些基類時,會形成菱形結構,導致兩個核心問題:

  • 數(shù)據(jù)冗余:共同基類的成員會在派生類中存在多份副本;
  • 二義性:訪問共同基類的成員時,編譯器無法確定訪問哪一份副本。

菱形繼承示例(有問題)

#include <iostream>
using namespace std;

// 共同基類:動物
class Animal {
public:
    int age; // 共同成員
    Animal(int a) : age(a) {}
};

// 基類1:飛行動物(繼承Animal)
class Flyable : public Animal {
public:
    Flyable(int a) : Animal(a) {}
    void fly() { cout << "能飛,年齡:" << age << endl; }
};

// 基類2:游泳動物(繼承Animal)
class Swimmable : public Animal {
public:
    Swimmable(int a) : Animal(a) {}
    void swim() { cout << "能游泳,年齡:" << age << endl; }
};

// 派生類:鴨子(同時繼承Flyable和Swimmable)
class Duck : public Flyable, public Swimmable {
public:
    // 問題1:構造函數(shù)需要初始化兩次Animal(數(shù)據(jù)冗余)
    Duck(int a) : Flyable(a), Swimmable(a) {}
    void quack() { cout << "嘎嘎叫" << endl; }
};

int main() {
    Duck duck(2);
    // 問題2:訪問age會觸發(fā)二義性編譯錯誤
    // cout << duck.age << endl; // 報錯:ambiguous reference to 'age'
    
    // 強行指定作用域可以訪問,但本質是兩份age(數(shù)據(jù)冗余)
    cout << duck.Flyable::age << endl;   // 2
    cout << duck.Swimmable::age << endl; // 2
    return 0;
}

關鍵問題分析

  • Duck對象中存在兩份age(分別來自Flyable和Swimmable),即使初始化值相同,也是獨立的內(nèi)存空間;
  • 直接訪問duck.age會編譯報錯,因為編譯器不知道你要訪問哪一份age;
  • 這種冗余不僅浪費內(nèi)存,還可能導致邏輯錯誤(比如修改其中一份,另一份不變)。

二、虛繼承(Virtual Inheritance)

1. 基本概念

虛繼承是C++為解決菱形繼承的二義性和數(shù)據(jù)冗余設計的機制:通過virtual關鍵字聲明繼承,讓“共同基類”成為虛基類,此時無論派生多少次,共同基類在最終派生類中只保留一份實例。

語法格式

class 派生類名 : virtual 繼承方式 基類名 {
    // 成員
};
  • virtual關鍵字加在“繼承方式”前;
  • 核心作用:讓共同基類的實例在最終派生類中唯一。

2. 虛繼承解決菱形繼承的示例

修改上面的代碼,給FlyableSwimmable的繼承加virtual

#include <iostream>
using namespace std;
// 共同基類:動物
class Animal {
public:
    int age;
    Animal(int a) : age(a) {
        cout << "Animal構造:age=" << a << endl;
    }
};
// 虛繼承Animal:飛行動物
class Flyable : virtual public Animal {
public:
    // 虛繼承下,這里的構造函數(shù)不會直接初始化Animal(由最終派生類統(tǒng)一初始化)
    Flyable(int a) : Animal(a) {}
    void fly() { cout << "能飛,年齡:" << age << endl; }
};
// 虛繼承Animal:游泳動物
class Swimmable : virtual public Animal {
public:
    Swimmable(int a) : Animal(a) {}
    void swim() { cout << "能游泳,年齡:" << age << endl; }
};
// 最終派生類:鴨子
class Duck : public Flyable, public Swimmable {
public:
    // 虛繼承下,最終派生類必須直接初始化虛基類Animal(唯一入口)
    Duck(int a) : Animal(a), Flyable(a), Swimmable(a) {}
    void quack() { cout << "嘎嘎叫" << endl; }
};
int main() {
    Duck duck(2);
    // 無二義性:只有一份age
    cout << duck.age << endl; // 輸出2
    duck.fly();  // 能飛,年齡:2
    duck.swim(); // 能游泳,年齡:2
    return 0;
}

輸出

Animal構造:age=2
2
能飛,年齡:2
能游泳,年齡:2

關鍵變化:

  1. 數(shù)據(jù)冗余解決:Duck對象中只有一份age,不再有重復副本;
  2. 二義性解決:直接訪問duck.age無編譯錯誤,編譯器明確知道訪問唯一的age;
  3. 構造規(guī)則變化:虛基類的構造函數(shù)由最終派生類統(tǒng)一初始化(即使中間基類寫了初始化,也會被忽略),保證虛基類只構造一次。

3. 虛繼承的底層原理

虛繼承的實現(xiàn)依賴編譯器的虛基類表(vbtable)

  • 每個虛繼承的類會存儲一個指向“虛基類表”的指針;
  • 虛基類表記錄了當前類到虛基類實例的偏移量;
  • 通過這個表,所有派生類都能找到唯一的虛基類實例,避免冗余和二義性。

提示:虛繼承有輕微的性能開銷(指針訪問+表查詢),因此僅在需要解決菱形繼承時使用,不要濫用。

三、總結

  1. 多重繼承:允許一個類繼承多個基類,復用多類特性,但會引發(fā)菱形繼承的數(shù)據(jù)冗余二義性問題;
  2. 虛繼承:通過virtual關鍵字聲明繼承,將共同基類變?yōu)樘摶?,使其在最終派生類中僅保留一份實例,解決菱形繼承的核心問題;
  3. 關鍵規(guī)則:虛基類的構造函數(shù)由最終派生類統(tǒng)一初始化,中間基類對虛基類的初始化會被編譯器忽略。

補充:多重繼承的其他注意事項

  • 如果多個基類有同名方法,即使不是菱形繼承,訪問時也需要指定作用域(比如duck.Flyable::func());
  • 實際開發(fā)中,應盡量避免復雜的多重繼承(可通過組合/接口替代),僅在確有必要時使用;
  • C++11后的std::enable_shared_from_this、Qt的QObject等經(jīng)典場景會用到虛繼承。

到此這篇關于c++中多重繼承與虛繼承的實現(xiàn)的文章就介紹到這了,更多相關c++ 多重繼承與虛繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++之動態(tài)數(shù)組vector解讀

    C++之動態(tài)數(shù)組vector解讀

    這篇文章主要介紹了C++之動態(tài)數(shù)組vector解讀,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Opencv 馬賽克和毛玻璃效果與圖片融合的實現(xiàn)

    Opencv 馬賽克和毛玻璃效果與圖片融合的實現(xiàn)

    這篇文章主要為大家詳細介紹了通過OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡效果與圖片的融合,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 解讀C++編程的相關文件操作

    解讀C++編程的相關文件操作

    這篇文章主要介紹了解讀C++編程的相關文件操作,是C++入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • C語言模擬實現(xiàn)密碼輸入的示例代碼

    C語言模擬實現(xiàn)密碼輸入的示例代碼

    本文主要介紹了C語言模擬實現(xiàn)密碼輸入的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語言實現(xiàn)自動發(fā)牌程序

    C語言實現(xiàn)自動發(fā)牌程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)自動發(fā)牌程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言從編譯到運行過程詳解

    C語言從編譯到運行過程詳解

    這篇文章主要介紹了C語言從編譯到運行的一個過程的相關資料,需要的朋友可以參考下面文章具體的內(nèi)容
    2021-09-09
  • 詳解C語言結構體中的函數(shù)指針

    詳解C語言結構體中的函數(shù)指針

    這篇文章主要介紹了詳解C語言結構體中的函數(shù)指針,文中對函數(shù)指針的基本概念也有講解,需要的朋友可以參考下
    2016-04-04
  • C語言中數(shù)組的一些基本知識小結

    C語言中數(shù)組的一些基本知識小結

    這篇文章主要介紹了C語言中數(shù)組的一些基本知識小結,其中重點是對于數(shù)組的內(nèi)存分配相關方面的知識整理,需要的朋友可以參考下
    2016-04-04
  • C語言實現(xiàn)掃雷算法簡易版

    C語言實現(xiàn)掃雷算法簡易版

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)掃雷算法簡易版,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C++運算符重載與多繼承及二義性詳解

    C++運算符重載與多繼承及二義性詳解

    繼友元知識過后,就到了今天的C++運算符重載的內(nèi)容了,運算符重載是C++里比較重要的內(nèi)容。這篇博文不會一下子講完各種運算符重載,因為太多了了也不好吸收掌握,所以運算符重載我準備分多次記錄和分享,那么接下來進入正文
    2022-11-11

最新評論

新建县| 湖口县| 江山市| 泸溪县| 公主岭市| 甘洛县| 南靖县| 邢台市| 嘉兴市| 青海省| 灵宝市| 永靖县| 梨树县| 札达县| 宜兴市| 普安县| 建始县| 台北市| 唐海县| 乐业县| 西丰县| 湟中县| 富裕县| 贡嘎县| 鄂伦春自治旗| 读书| 兴仁县| 凤庆县| 瑞金市| 南康市| 桂阳县| 颍上县| 龙井市| 巴塘县| 内江市| 太仆寺旗| 铜鼓县| 剑河县| 郧西县| 林芝县| 黔南|