C++中的繼承:從基礎到復雜

目錄

前言

1. 繼承的基本概念

2. 繼承方式與訪問控制

3. 派生類與基類的對象轉換

4. 繼承中的作用域

5. 派生類的默認成員函數

6. 繼承中的特殊關系

6.1 繼承與友元

6.2 繼承與靜態成員

7. 復雜的菱形繼承問題

8. 繼承與組合的選擇

9. 常見面試題

總結


前言

繼承是面向對象編程中最重要的概念之一,它允許我們創建新的類(派生類)基于已有類(基類)的特性進行擴展。在C++中,繼承機制提供了代碼復用的強大手段,同時也帶來了許多需要注意的細節和復雜性。本文將全面介紹C++中的繼承機制,從基本概念到高級應用,幫助讀者深入理解這一重要主題。


1. 繼承的基本概念

繼承允許派生類復用基類的成員(包括成員變量和成員函數),同時可以添加新的特性或修改現有行為。這種機制體現了面向對象編程中"由簡單到復雜"的認知過程。
?

class Person {
public:void Print() {cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter";int _age = 18;
};class Student : public Person {
protected:int _stuid; // 學號
};


?

在這個例子中,`Student`類通過公有繼承獲得了`Person`類的所有成員,同時添加了自己的特有成員`_stuid`。

2. 繼承方式與訪問控制

C++提供了三種繼承方式:public、protected和private。不同的繼承方式會影響基類成員在派生類中的訪問權限。

基類成員/繼承方式public繼承protected繼承private繼承
public成員publicprotectedprivate
protected成員protectedprotectedprivate
private成員不可見不可見不可見

重要規則:
1. 基類的private成員在派生類中不可見
2. 成員在派生類中的訪問權限 = min(成員在基類的訪問權限, 繼承方式)
3. class默認private繼承,struct默認public繼承(但建議顯式指定)

3. 派生類與基類的對象轉換

派生類對象可以賦值給基類對象/指針/引用,這種現象稱為"切片"或"切割"。


?

Student sobj;
Person pobj = sobj; ?// 切片
Person* pp = &sobj; ?// 指針
Person& rp = sobj; ? // 引用


?

但反過來不行,除非使用強制類型轉換(需謹慎使用)。

4. 繼承中的作用域

基類和派生類有獨立的作用域。當派生類與基類有同名成員時,派生類成員會隱藏基類成員(稱為"隱藏"或"重定義")。
?

class Person {
protected:int _num = 111; // 身份證號
};class Student : public Person {
public:void Print() {cout << "身份證號:" << Person::_num << endl; // 顯式訪問cout << "學號:" << _num << endl;}
protected:int _num = 999; // 學號
};


?

5. 派生類的默認成員函數

派生類的6個默認成員函數有其特殊性:

1. 構造函數必須調用基類構造函數初始化基類部分
2. 拷貝構造必須調用基類拷貝構造
3. operator=必須調用基類operator=
4. 析構函數會自動調用基類析構函數(先派生后基類)
5. 對象初始化順序:先基類構造,再派生類構造
6. 對象析構順序:先派生類析構,再基類析構

6. 繼承中的特殊關系

6.1 繼承與友元

友元關系不能繼承,基類的友元不能訪問派生類的私有和保護成員。

6.2 繼承與靜態成員

基類定義的靜態成員在整個繼承體系中只有一個實例,無論派生出多少子類。
?

class Person {
public:static int _count; // 統計人數
};
int Person::_count = 0;class Student : public Person { /*...*/ };
class Graduate : public Student { /*...*/ };// 所有類共享同一個_count


?

7. 復雜的菱形繼承問題

菱形繼承是多繼承的一種特殊情況,會導致數據冗余和二義性問題。


class Person { /*...*/ };
class Student : public Person { /*...*/ };
class Teacher : public Person { /*...*/ };
class Assistant : public Student, public Teacher { /*...*/ };

?

解決方案是使用**虛擬繼承**:


?

class Student : virtual public Person { /*...*/ };
class Teacher : virtual public Person { /*...*/ };
class Assistant : public Student, public Teacher { /*...*/ };


?

虛擬繼承通過虛基表指針和虛基表解決數據冗余和二義性問題。

8. 繼承與組合的選擇

- 繼承表示"is-a"關系(如BMW是一種Car)
- 組合表示"has-a"關系(如Car有Tire)

設計原則:
1. 優先使用對象組合而非類繼承
2. 繼承會破壞封裝,增加耦合度
3. 組合保持類封裝,耦合度低
4. 需要多態時必須使用繼承

?

// 繼承示例
class BMW : public Car { /*...*/ };// 組合示例
class Car {
protected:Tire _t; // 輪胎
};


?

9. 常見面試題

1. 什么是菱形繼承?它的問題是什么?
2. 虛擬繼承如何解決數據冗余和二義性?
3. 繼承和組合的區別?何時使用它們?


總結

C++的繼承機制強大但復雜,特別是多繼承和菱形繼承。理解繼承的各種細節對于編寫健壯、可維護的面向對象代碼至關重要。在實際開發中,應當謹慎使用多繼承,優先考慮組合而非繼承,只有在確實需要表達"is-a"關系或實現多態時才使用繼承。

通過本文的學習,希望讀者能夠掌握C++繼承的核心概念,理解其底層原理,并能夠在實際項目中做出恰當的設計選擇。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92362.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92362.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Eyevinn 徹底改變開源部署模式

該咨詢公司借助Akamai云平臺&#xff0c;為其創新的開源平臺和可持續收益分成模式提供強大支持。 "時間就是金錢&#xff0c;我們通過Akamai云平臺快速將開源云平臺投入生產。" ——Eyevinn Technology研發副總裁 Jonas Birm實現可持續視頻流媒體服務 自2013年以來&…

17day-人工智能-機器學習-分類算法-KNN

1. 什么是knn算法knn算法全名叫做k-近鄰算法&#xff08;K-Nearest Neighbors&#xff0c;簡稱KNN&#xff09;&#xff0c;看到名字是不是能想到是算距離的&#xff0c;第一個k是指超參數的意思&#xff0c;就是可以認為設置的意思&#xff0c;這里是指最近的k個樣本。2. 為什…

12-netty基礎-手寫rpc-編解碼-04

netty系列文章&#xff1a; 01-netty基礎-socket02-netty基礎-java四種IO模型03-netty基礎-多路復用select、poll、epoll04-netty基礎-Reactor三種模型05-netty基礎-ByteBuf數據結構06-netty基礎-編碼解碼07-netty基礎-自定義編解碼器08-netty基礎-自定義序列化和反序列化09-n…

解決 Windows 下的“幽靈文件”——記一次與帶空格的 .gitignore 文件的艱難斗爭

引言 你是否遇到過這樣的情況&#xff1a;一個文件明明躺在你的文件夾里&#xff0c;ls 或 dir 命令都能清楚地看到它&#xff0c;但無論你用什么方法嘗試刪除&#xff0c;系統都冷酷地告訴你“找不到文件”&#xff1f; 就在今天&#xff0c;我就遇到了這樣一個“幽靈”般的 .…

(易視寶)易視TV is-E4-G-全志A20芯片-安卓4-燒寫卡刷工具及教程

&#xff08;易視寶&#xff09;易視TV is-E4-G-全志A20芯片-安卓4-燒寫卡刷工具及教程PhoenixCard_V309燒錄步驟&#xff1a;1、將TF或SD卡插入計算機&#xff0c;打開軟件&#xff1b;2、選擇固件所在目錄&#xff1b;3、燒寫模式選“卡量產”4、點擊“燒錄”開始量產&#x…

(數據結構)順序表實現-增刪查改

1.線性表 線性表(linear list)是n個具有相同特性的數據元素的有限序列。線性表是一種在實際中廣泛使用的數據結構,常見的線性表:順序表、鏈表、棧、隊列、字符串… 線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上并不一定是連續的,線性表在物理上存儲時…

【面試八股總結】線程/進程同步問題

一、同步與互斥 在線程并發執行的過程中&#xff0c;進程/線程之間存在協作的關系&#xff0c;例如有互斥、同步的關系。為了實現進程/線程間正確的協作&#xff0c;操作系統必須提供實現進程協作的措施和方法&#xff0c;主要的方法有兩種&#xff1a; 鎖&#xff1a;加鎖、解…

大語言模型提示工程與應用:提示工程入門指南

提示工程入門 學習目標 在本課程中&#xff0c;我們將學習提示工程。 相關知識點 提示工程 學習內容 1 提示工程 提示工程是一門新興學科&#xff0c;專注于設計和優化提示詞以高效利用語言模型完成多樣化任務。掌握提示工程能幫助開發者更深入理解大語言模型(LLM)的能力…

PostgreSQL 多級依賴血緣系統的設計與落地

一、業務背景&#xff1a;三類指標與四種狀態指標類型定義規則依賴關系原子指標單表聚合&#xff08;SELECT WHERE GROUP&#xff09;無派生指標在原子/派生指標上加 WHERE、改 GROUP依賴 1~N 個父指標復合指標多個原子/派生指標做加減運算依賴 1~N 個父指標狀態說明已保存草…

阿里云百煉平臺創建智能體-上傳文檔

整體思路是&#xff1a; 1創建ram用戶&#xff0c;授權 2上傳文件獲取FileSession 3調用智能體對話&#xff0c;傳入FileSession 接下來每個步驟的細節&#xff1a; 1官方不推薦使用超級管理員用戶獲得accessKeyId和accessKeySecret&#xff0c;所以登錄超級管理員賬號創建…

剪映里面導入多張照片,p圖后如何再導出多張照片?

剪映普通版本暫時沒發現可以批量導出圖片。這里采用其他方式實現。先整體導出視頻。這里前期要注意設置幀率&#xff0c;一張圖片的時長。 參考一下設置&#xff0c;幀率設置為30&#xff0c;圖片導入時長設置為1s&#xff0c;這樣的話&#xff0c;方便后期把視頻切割為單幀。導…

怎么查看Linux I2C總線掛載了那些設備?

1. 根據系統啟動查看設備樹節點文件&#xff08;系統運行后的&#xff09; 比如&#xff1a;要查看I2C2i2c2: i2cfeaa0000 {compatible "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";reg <0x0 0xfeaa0000 0x0 0x1000>;clocks <&cru CLK_…

bat腳本實現獲取非微軟官方服務列表

Get-CimInstance -ClassName Win32_Service |Where-Object { $_.State -eq Running -and $_.StartMode -ne Disabled } | ForEach-Object {$isMicrosoft $false$signerInfo 無可執行路徑if ($_.PathName) {# 提取可執行文件路徑&#xff08;處理帶引號/參數的路徑&#xff09…

小程序難調的組件

背景。做小程序用到了自定義表單。前后端都是分開寫的&#xff0c;沒有使用web-view。所以要做到功能對稱時間選擇器。需要區分datetime, year, day等類型使用uview組件較方便 <template><view class"u-date-picker" v-if"visible"><view c…

從零構建TransformerP2-新聞分類Demo

歡迎來到啾啾的博客&#x1f431;。 記錄學習點滴。分享工作思考和實用技巧&#xff0c;偶爾也分享一些雜談&#x1f4ac;。 有很多很多不足的地方&#xff0c;歡迎評論交流&#xff0c;感謝您的閱讀和評論&#x1f604;。 目錄引言1 一個完整的Transformer模型2 需要準備的“工…

qt qml實現電話簿 通訊錄

qml實現電話簿&#xff0c;基于github上開源代碼修改而來&#xff0c;增加了搜索和展開&#xff0c;效果如下 代碼如下 #include <QGuiApplication> #include <QQmlApplicationEngine>int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_…

順序表——C語言

順序表實現代碼解析與學習筆記一、順序表基礎概念順序表是線性表的一種順序存儲結構&#xff0c;它使用一段連續的內存空間&#xff08;數組&#xff09;存儲數據元素&#xff0c;通過下標直接訪問元素&#xff0c;具有隨機訪問的特性。其核心特點是&#xff1a;元素在內存中連…

【Oracle篇】Oracle Data Pump遠程備份技術:直接從遠端數據庫備份至本地環境

&#x1f4ab;《博主主頁》&#xff1a;    &#x1f50e; CSDN主頁__奈斯DB    &#x1f50e; IF Club社區主頁__奈斯、 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對…

Linux系統--文件系統

大家好&#xff0c;我們今天繼續來學習Linux系統部分。上一次我們學習了內存級的文件&#xff0c;下面我們來學習磁盤級的文件。那么話不多說&#xff0c;我們開始今天的學習&#xff1a; 目錄 Ext系列?件系統 1. 理解硬件 1-1 磁盤、服務器、機柜、機房 1-2 磁盤物理結構…

KUKA庫卡焊接機器人氬氣節氣設備

在焊接生產過程中&#xff0c;氬氣作為一種重要的保護氣體被廣泛應用于KUKA庫卡焊接機器人的焊接操作中。氬氣的消耗往往是企業生產成本的一個重要組成部分&#xff0c;因此實現庫卡焊接機器人節氣具有重要的經濟和環保意義。WGFACS節氣裝置的出現為解決這一問題提供了有效的方…