C++繼承:構建類層級結構的關鍵技術

一、繼承的基本概念

繼承是面向對象程序設計的基本特徵之一。在C++語言中,繼承允許我們定義一個新的類,這個新類繼承已有的類的屬性和行為,從而可以重複使用已有類的代碼,避免代碼冗餘。

在C++中,通過在類定義中使用「:」符號,來指定一個類從另一個類繼承而來。被繼承的類稱為基類,新定義的類稱為派生類。派生類可以繼承基類的公有成員、保護成員和私有成員,但只有公有成員能夠被外部程序訪問。

class BaseClass {
public:
    void publicFunc() { //公有函數
        std::cout << "BaseClass 的 publicFunc() 函數" << std::endl;
    }
protected:
    void protectedFunc() { // 保護函數
        std::cout << "BaseClass 的 protectedFunc() 函數" << std::endl;
    }
private:
    void privateFunc() { // 私有函數
        std::cout << "BaseClass 的 privateFunc() 函數" << std::endl;
    }
};

class DerivedClass : public BaseClass {
public:
    void callPublicFunc() {
        publicFunc(); // 從基類繼承的公有函數
    }
    void callProtectedFunc() {
        protectedFunc(); // 從基類繼承的保護函數
    }
   //void callPrivateFunc() { privateFunc(); }; 該語句會編譯錯誤
};

int main() {
    DerivedClass obj; 
    obj.callPublicFunc(); //調用從基類繼承而來的公有成員函數
    obj.callProtectedFunc(); //調用從基類繼承而來的保護成員函數
    //obj.callPrivateFunc(); //編譯錯誤,私有成員函數不能被訪問
    return 0;
}

二、繼承類型

在C++中,繼承被分為三類:公有繼承、保護繼承和私有繼承。

1.公有繼承

公有繼承是最常用的繼承方式,它指定派生類能夠繼承基類的公有成員和保護成員。在公有繼承中,基類的公有成員和保護成員在派生類中的訪問許可權不變。

class BaseClass {
public:
    void publicFunc() { 
        std::cout << "BaseClass 的公有函數" << std::endl;
    }
protected:
    void protectedFunc() { 
        std::cout << "BaseClass 的保護函數" << std::endl;
    }
};

class DerivedClass : public BaseClass {
    //從基類繼承而來的公有成員和保護成員在DerivedClass中的訪問許可權不變
};

int main() {
    DerivedClass obj; 
    obj.publicFunc(); //從基類繼承而來的公有成員函數可以在外部程序中被訪問
    //obj.protectedFunc(); 非法,派生類外不能訪問基類的保護成員
    return 0;
}

2.保護繼承

保護繼承與公有繼承類似,不同之處在於基類的公有成員和保護成員在派生類中都成為保護成員,在派生類外部不能訪問。只有派生類的成員函數或友元函數能夠訪問它們。

class BaseClass {
public:
    void publicFunc() { 
        std::cout << "BaseClass 的公有函數" << std::endl;
    }
protected:
    void protectedFunc() { 
        std::cout << "BaseClass 的保護函數" << std::endl;
    }
};

class DerivedClass : protected BaseClass {
    //從基類繼承而來的公有成員和保護成員在DerivedClass中成為保護成員,其他程序不能訪問
public:
    void callProtectedFunc() {
        protectedFunc(); //從基類繼承而來的保護函數可以在派生類中被訪問
    }
};

int main() {
    DerivedClass obj; 
    //obj.publicFunc(); 非法,從基類繼承而來的公有成員在派生類外部不能訪問
    //obj.protectedFunc(); 非法,從基類繼承而來的保護成員在派生類外部不能訪問
    obj.callProtectedFunc(); //從基類繼承而來的保護函數可以在派生類中被訪問
    return 0;
}

3.私有繼承

私有繼承意味著基類的公有和保護成員在派生類中均成為私有成員,只有派生類的成員函數或友元函數能夠訪問它們。私有繼承不會帶來新的介面。

class BaseClass {
public:
    void publicFunc() { 
        std::cout << "BaseClass 的公有函數" << std::endl;
    }
protected:
    void protectedFunc() { 
        std::cout << "BaseClass 的保護函數" << std::endl;
    }
};

class DerivedClass : private BaseClass {
    //從基類繼承而來的公有成員和保護成員在DerivedClass中均為私有成員
public:
    void callProtectedFunc() {
        protectedFunc(); //從基類繼承而來的保護函數可以在派生類中被訪問
    }
};

int main() {
    DerivedClass obj; 
    //obj.publicFunc(); 非法,從基類繼承而來的公有成員在派生類外部不能訪問
    //obj.protectedFunc(); 非法,從基類繼承而來的保護成員在派生類外部不能訪問
    obj.callProtectedFunc(); //從基類繼承而來的保護函數可以在派生類中被訪問
    return 0;
}

三、構造函數和析構函數中的繼承

在進行繼承時,基類的構造函數和析構函數會被自動調用。

在構造派生類的對象時,首先會調用基類的默認構造函數,然後調用派生類的構造函數。當然,也可以在派生類的構造函數中顯式調用基類的構造函數。考慮以下代碼:

class BaseClass {
public:
    BaseClass() { //基類的默認構造函數
        std::cout << "BaseClass 的構造函數" << std::endl;
    }
    ~BaseClass() { //基類的析構函數
        std::cout << "BaseClass 的析構函數" << std::endl;
    }
};

class DerivedClass : public BaseClass {
public:
    DerivedClass() { //派生類的構造函數
        std::cout << "DerivedClass 的構造函數" << std::endl;
    }
    ~DerivedClass() { //派生類的析構函數
        std::cout << "DerivedClass 的析構函數" << std::endl;
    }
};

int main() {
    DerivedClass obj; //創建一個派生類的對象
    return 0;
}

執行上述代碼,將輸出以下結果:

BaseClass 的構造函數
DerivedClass 的構造函數
DerivedClass 的析構函數
BaseClass 的析構函數

在析構派生類的對象時,先調用派生類的析構函數,然後調用基類的析構函數。同樣,也可以在派生類的析構函數中顯式調用基類的析構函數。

四、虛函數和多態

虛函數是C++用於實現多態的重要機制。在基類中聲明一個虛函數,派生類可以根據其需求重新定義這個虛函數,以實現多態性。在調用虛函數時,函數的實際調用取決於對象的類型,而不是指向該對象的指針或引用類型。例如:

class BaseClass {
public:
    virtual void virtualFunc() { 
        std::cout << "BaseClass 的虛函數" << std::endl;
    }
};

class DerivedClass : public BaseClass {
public:
    void virtualFunc() { //重定義基類的虛函數
        std::cout << "DerivedClass 的虛函數" << std::endl;
    }
};

int main() {
    DerivedClass obj; //創建一個派生類的對象
    BaseClass& ref = obj; //使用基類的引用來引用派生類的對象
    ref.virtualFunc(); //調用「引用的對象」的虛函數
    return 0;
}

以上代碼中,我們聲明了一個基類和一個派生類,基類中的虛函數被派生類重定義,使得它們的實現不同。在main函數中,創建了一個派生類對象,並用基類的引用來引用該對象,最後調用了該對象的虛函數。由於虛函數是根據對象類型而不是引用類型確定的,因此程序將調用派生類的虛函數,輸出以下內容:

DerivedClass 的虛函數

五、抽象類

抽象類是具有至少一個純虛函數的類,不能直接實例化,只能作為其他類的基類使用。純虛函數沒有函數體,只有函數原型。在基類中聲明純虛函數後,在派生類中必須定義該函數,否則將編譯錯誤。

class AbstractClass { //抽象類
public:
    virtual void pureVirtualFunc() = 0; //純虛函數
};

class DerivedClass : public AbstractClass {
public:
    void pureVirtualFunc() { 
        std::cout << "DerivedClass 實現了純虛函數 pureVirtualFunc()" << std::endl;
    }
};

int main() {
    //AbstractClass obj; 非法,抽象類不能直接實例化
    DerivedClass obj; //創建一個派生類的對象
    AbstractClass& ref = obj; //使用基類的引用來引用派生類的對象
    ref.pureVirtualFunc(); //調用「引用的對象」的純虛函數
    return 0;
}

在以上示例中,AbstractClass 是一個抽象類,定義了一個純虛函數。派生類DerivedClass 定義了純虛函數 pureVirtualFunc() 的實現,使得該派生類不再是抽象類。最後,創建了一個DerivedClass 對象,並用基類的引用來引用它,並調用了該對象的純虛函數。

六、總結

在C++中,繼承是構建類層級結構的關鍵技術之一。通過繼承,我們可以重用已有的類的代碼,提高程序的可維護性和可擴展性。C++中的繼承有三種類型:公有繼承、保護繼承和私有繼承。

C++中的構造函數和析構函數在進行繼承時,會自動調用。虛函數和多態則是C++實現動態多態的重要機制。抽象類不能直接實例化,必須作為其他類的基類使用。

了解和掌握C++中的繼承及相關特性,有助於我們構建更加複雜的類層級結構,提高

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/256550.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-15 12:41
下一篇 2024-12-15 12:41

相關推薦

  • Vue TS工程結構用法介紹

    在本篇文章中,我們將從多個方面對Vue TS工程結構進行詳細的闡述,涵蓋文件結構、路由配置、組件間通訊、狀態管理等內容,並給出對應的代碼示例。 一、文件結構 一個好的文件結構可以極…

    編程 2025-04-29
  • Python程序的三種基本控制結構

    控制結構是編程語言中非常重要的一部分,它們指導著程序如何在不同的情況下執行相應的指令。Python作為一種高級編程語言,也擁有三種基本的控制結構:順序結構、選擇結構和循環結構。 一…

    編程 2025-04-29
  • Lidar避障與AI結構光避障哪個更好?

    簡單回答:Lidar避障適用於需要高精度避障的場景,而AI結構光避障更適用於需要快速響應的場景。 一、Lidar避障 Lidar,即激光雷達,通過激光束掃描環境獲取點雲數據,從而實…

    編程 2025-04-27
  • Switch C:多選結構的利器

    在編寫程序時,我們經常需要根據某些條件執行不同的代碼,這時就需要使用選擇結構。在C語言中,有if語句、switch語句等多種選擇結構可供使用。其中,switch語句是一種非常強大的…

    編程 2025-04-25
  • Python分支結構的詳細闡述

    一、if語句的基本語法 if 條件: 代碼語句1 代碼語句2 …… if語句是Python分支結構中最基本也是最常用的結構,它的基本語法如上所示。if語句會先判斷條件是否成立,如果…

    編程 2025-04-24
  • 深入理解 Vue 目錄結構

    Vue 是一款由 Evan You 開發的流行 JavaScript 框架。Vue 具有響應式視圖和組件化的思想,讓開發者可以輕鬆構建互動式的 Web 應用。那麼在 Vue 開發中…

    編程 2025-04-24
  • JS遞歸遍歷樹結構詳解

    一、JS遞歸遍歷樹結構並修改 function traverse(node) { if(node == null) return; //遍歷結束 node.value++; // …

    編程 2025-04-24
  • 詳解數組結構

    一、數組的基本概念 數組是一種有序的數據結構,可以容納一組相同數據類型的元素。每個元素有一個唯一的索引(下標),可以通過下標來訪問數組的元素。數組一般分為一維和多維,也可以具有不同…

    編程 2025-04-23
  • 殘差結構:從原理到應用

    一、殘差結構的原理 殘差結構在深度學習中的應用越來越廣泛,其核心原理是將輸入特徵和參考特徵拼接在一起進行訓練,以增強模型的學習能力和泛化能力。 具體地,殘差結構引入了跨層連接,使得…

    編程 2025-04-23
  • LTE幀結構詳解

    一、幀結構簡介 LTE網路中的幀結構是由多個子幀和時隙構成的。每個子幀由14個符號組成,符號的長度為0.5ms。每個符號中又包含7個資源塊,一個資源塊可以傳輸12個子載波。一個子幀…

    編程 2025-04-22

發表回復

登錄後才能評論