六、繼承(一)

1 繼承的引入

以往我們想分別實現描述學生、老師的類,可能會這樣子做:

class Student
{string _name;string _number;int _tel;int id;string _address;int _age;
};
class Teacher
{string _name;int _level;int _tel;int id;string _address;int _age;
};

但從這兩個類的結構可以看到它們的內容是高度重復的,有沒有什么辦法能將幾個類公共的部分提取出來,又能保留其獨有的特性呢?

這就要用到C++的繼承機制。

2 繼承的概念及定義

2.1 繼承的概念

繼承機制是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在保持原有類特性的基礎上進行擴展,增加功能,這樣產生新的類,稱派生類。繼承呈現了面向對象程序設計的層次結構,體現了由簡單到復雜的認知過程。以前我們接觸的復用都是函數復用,而繼承是類設計層次的復用

例:

#include <iostream>
#include <string>
using namespace std;
class Person//父類Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; //姓名int _age = 18;  //年齡
};class Student : public Person//子類Student
{
protected:int _stuid; //學號
};class Teacher : public Person//子類Teacher
{
protected:int _jobid; //工號
};
int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}

運行結果:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

從運行結果可以看到,繼承后父類的Person的成員(成員函數和成員變量)都會變成子類的一部分,這里體現出了StudentTeacher復用了Person的成員。

2.2 繼承的定義

2.2.1 繼承的定義格式

我們以剛才的例子為例,講解一下繼承的定義格式。

//     派生類    繼承方式  基類|         |      ||         |      |
class Student : public Person
{
protected:int _stuid;
};
2.2.2 繼承關系和訪問限定符

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

2.2.3 繼承基類成員訪問方式的變化
類成員/繼承方式public繼承protected繼承private繼承
基類的public成員派生類的public成員派生類的protected成員派生類的private成員
基類的protected成員派生類的protected成員派生類的protected成員派生類的private成員
基類的private成員在派生類中不可見在派生類中不可見在派生類中不可見

總結:

  1. 基類private成員在派生類中無論以什么方式繼承都是不可見的。這里的不可見是指基類的私有成員還是被繼承到了派生類對象中,但是語法上限制派生類對象不管在類里面還是類外面都不能去訪問它。
  2. 基類private成員在派生類中是不能被訪問,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected。可以看出保護成員限定符是因繼承才出現的。
  3. 實際上面的表格我們進行一下總結會發現,基類的私有成員在子類都是不可見。基類的其他成員在子類的訪問方式 == Min(成員在基類的訪問限定符,繼承方式),public > protected > private。
  4. 使用關鍵字class時默認的繼承方式是private,使用struct時默認的繼承方式是public,不過最好顯式寫出繼承方式。
  5. 在實際運用中一般使用都是public繼承,幾乎很少使用protetced/private繼承,也不提倡使用protetced/private繼承,因為protetced/private繼承下來的成員都只能在派生類的類里面使用,實際中擴展維護性不強。

例:

3 基類和派生類對象賦值轉換

3.1 基類和派生類對象賦值轉換引入

我們先來看下面這段代碼:

double d = 1.1;
int i = d;

以前我們說d要賦值給i會產生一個具有常性的臨時變量,這是隱式類型轉換。

那么現在有這樣一個問題:

Student s;
Person p = s;

在公有繼承下,一個派生類的對象能不能賦給一個基類的對象呢?

這就涉及到基類和派生類對象間的賦值轉換。

3.2 基類和派生類對象賦值轉換的規則

在公有繼承下,基類和派生類對象間賦值轉換需遵守以下規則:

  1. 派生類對象可以賦值給基類的對象基類的指針基類的引用,這里有個形象的說法叫切片或者切割,寓意把派生類中基類那部分切下來賦值過去。

  2. 基類對象不能賦值給派生類對象。

  3. 基類的指針或者引用可以通過強制類型轉換賦值給派生類的指針或者引用。但是必須是基類的指針是指向派生類對象時才是安全的。這里基類如果是多態類型,可以使用RTTI(RunTime Type Information)dynamic_cast識別后進行安全轉換,這里先了解即可,后續會講解。

4 繼承中的作用域

  1. 在繼承體系中基類和派生類都有獨立的作用域。
  2. 如果子類和父類中有同名成員,那么子類成員將屏蔽父類對同名成員的直接訪問,這種情況叫隱藏,也叫重定義。(在子類成員函數中,可以使用基類::基類成員來進行顯示訪問)
  3. 需要注意的是如果是成員函數的隱藏,只需要函數名相同就構成隱藏。
  4. 在實際中,在繼承體系里面最好不要定義同名的成員。

5 派生類的默認成員函數

之前我們說過,每一個類都有6個默認成員函數,這個“默認”指的是如果我們自己不寫編譯器就會自動生成。

而在派生類中,這幾個成員函數的生成遵循以下規則:

  1. 派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。如果基類沒有默認的構造函數,則必須在派生類構造函數的初始化列表階段顯示調用。
  2. 派生類的拷貝構造函數必須調用基類的拷貝構造完成基類的拷貝初始化。
  3. 派生類的operator=必須要調用基類的operator=完成基類的復制。
  4. 派生類的析構函數會在被調用完成后自動調用基類的析構函數清理基類成員。因為這樣才能保證派生類對象先清理派生類成員再清理基類成員的順序。
  5. 派生類對象初始化先調用基類構造再調派生類構造。
  6. 派生類對象析構清理先調用派生類析構再調用基類的析構。
  7. 因為后續一些場景析構函數需要構成重寫,而重寫的條件之一是函數名相同,所以編譯器會對析構函數名進行特殊處理,處理成destrutor(),所以父類析構函數不加virtual的情況下,子類析構函數和父類析構函數構成隱藏關系,這一點在后續會進行講解。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

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

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

相關文章

【歸并排序】 詳細解析 動圖演示 逐圖解析 洛谷P1177【模板】排序 sort【快速排序】

文章目錄 歸并排序1.歸并排序的復雜度分析2.細節解釋3.歸并排序動圖演示3(1) 我們的拆分過程如下↓ 4.code↓ 洛谷P1177【模板】排序數據規模與約定code&#xff08;歸并排序&#xff09;↓code&#xff08;sort排序【快速排序】&#xff09; 完結撒花(&#xffe3;▽&#xff…

閱讀筆記 | REFORMER: THE EFFICIENT TRANSFORMER

閱讀論文&#xff1a; Kitaev, Nikita, ?ukasz Kaiser, and Anselm Levskaya. “Reformer: The efficient transformer.” arXiv preprint arXiv:2001.04451 (2020). 背景與動機 這篇論文發表較早&#xff0c;主要關注Transformer的效率問題。標準的Transformer模型在許多自然…

數據中臺:數字中國戰略關鍵技術實施

這里寫目錄標題 前言為何要建設數據中臺數據中臺建設痛點數據中臺學習資料聚焦前沿&#xff0c;方法論體系更新與時俱進&#xff0c;緊跟時代熱點深入6大行業&#xff0c;提煉實踐精華大咖推薦&#xff0c;數字化轉型必備案頭書 前言 在數字中國這一國家戰略的牽引下&#xff0…

測試基礎|質量保障體系從1到N的思考

在2023年,重點構建了團隊的質量保障體系,基本完成了從0到1的過程積累,也在多個不同的場合做了相關的分享,收獲了很多同行給的建議和意見。今年的首個工作目標是把這套質量保障體系運營好,去覆蓋更多的團隊,完成從1到N的過程,讓更多的團隊從這個質量體系中獲益,保障基本…

Node插件開發(1)-快速入門

在使用Electron開發客戶端時&#xff0c;如果現有Node模塊所提供的功能無法滿足需求&#xff0c;我們可以使用C開發自定義的Node模塊&#xff0c;也稱插件&#xff08;addon&#xff09;。 Node.js插件的擴展名為.node&#xff0c;是二進制文件&#xff0c;其本質上是動態鏈接…

基于springboot+vue的響應式企業員工績效考評系統(源碼+論文)

文章目錄 前言 一、功能設計 1 普通員工功能 2 主管功能 3 系統管理員功能 4 評分標準功能 5 PC端與手機端 6 制圖 二、功能實現 普通員工 1普通員工登錄 2公告板塊 3日志板塊 主管 1主管登錄 2公告板塊 3日志板塊 4績效評分板塊 5個人信息板塊 系統管理員…

TypeScript 日期格式化工具方法

工具方法 創建工具文件&#xff1a;util.ts /*** 獲取時間并格式化函數* param M 格式模板 如: YYYY-MM-DD ...* param Time 可選傳入時間參數 默認為 Now*/ export const getFormatDate (M: string, Time: Date | null | string | number null) > {let date: Date Tim…

在 Linux 環境下安裝 Kibana

目錄 一、Kibana 是什么 二、在 Linux 環境下安裝 Kibana 1、下載安裝包 2、解壓 3、修改 Kibana的配置文件 config/kibana.yml 4、啟動 5、瀏覽器登錄 Kibana 6、測試查詢 一、Kibana 是什么 Kibana 是通向 Elastic 產品集的窗口。 它可以在 Elasticsearch 中對數據進…

品牌推廣的兩種飛輪:非酋飛輪與歐皇飛輪

在品牌推廣的世界里&#xff0c;存在著兩種截然不同的飛輪效應&#xff0c;我們稱之為“非酋飛輪”與“歐皇飛輪”。這兩種飛輪象征著品牌發展的兩種不同路徑和策略&#xff0c;而迅騰文化則以其獨特的“繁”的原則&#xff0c;巧妙地將這兩種飛輪結合&#xff0c;助力品牌形成…

Linux安裝JumpServer并結合內網穿透實現公網訪問本地服務

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

Kubernetes 學習總結(46)—— Pod 不停重啟問題分析與解決

我們在做性能測試的時候&#xff0c;往往會發現我們的pod服務&#xff0c;頻繁重啟&#xff0c;通過kubectl get pods 命令&#xff0c;我們來逐步定位問題。 現象:running的pod&#xff0c;短時間內重啟次數太多。 定位問題方法:查看pod日志 kubectl get event …

【Element】實現基于 Element UI el-tabs 的左右滑動動畫

實現基于 Element UI el-tabs 的左右滑動動畫 引言 在構建現代 web 應用時&#xff0c;為用戶提供平滑的動畫效果是提升用戶體驗的關鍵。本篇博客將詳細介紹如何在使用 Vue 以及 Element UI 時&#xff0c;實現一個具有左右滑動效果的 tab 切換動畫。 使用 el-tabs 創建 tab…

Flutter 中的 SliverGrid 和 GridView:區別與使用場景

在 Flutter 中&#xff0c;SliverGrid 和 GridView 都是用于展示網格布局的組件&#xff0c;但它們有著不同的特點和適用場景。本文將介紹它們之間的區別以及在實際開發中的使用場景。 SliverGrid 和 GridView 的區別 SliverGrid&#xff1a; SliverGrid 是 CustomScrollView …

第十五屆藍橋杯第三期模擬賽題單

目錄 第一題&#xff1a; 第二題&#xff1a; 第三題&#xff1a; 第四題: 第五題&#xff1a; 第六題&#xff1a; 第七題 第八題 第九題 第十題 第一題 【問題描述】 請問 2023 有多少個約數&#xff1f;即有多少個正整數&#xff0c;使得 2023 是這個正整數的整數倍…

FolkMQ 是怎樣進行消息的事務處理?

FolkMQ 提供了二段式提交的事務提交的機制&#xff08;TCC 模型&#xff09;。允許生產者在發送消息時綁定到一個事務中并接收事務的管理&#xff0c;以確保消息的原子性&#xff08;要么全成功&#xff0c;要么全失敗&#xff09;。在 FolkMQ 中&#xff0c;事務是通過 MqTran…

1、EmlogCms代碼審計

一、SQL注入 1、后臺標簽刪除處存在1處sql注入 漏洞條件 ● 漏洞url: http://emlog6.0.com/admin/tag.php?actiondell_all_tag ● 漏洞參數&#xff1a;tag[xx] ● 是否存在限制&#xff1a;無 ● 是否還有其他條件&#xff1a;actiondell_all_tag,token復現 POST /admin…

擼chatgpt3.5 api backend-api 對接wxbot

功能是實現 web 轉api 對接wxbot用&#xff0c; 直接上代碼&#xff0c; 1.獲取wss url def get_register_websocket():# 請求頭url "https://chat.openai.com/backend-api/register-websocket"payload {}headers {Authorization: Bearer eyJhbGxxxxxxxxxxxxx…

docker的網絡配置

文章目錄 1、網絡模式1.1、bridge模式(默認模式)1.2、host模式 2、bridge模式3、自定義網絡 1、網絡模式 Docker在創建容器時有四種網絡模式&#xff1a;bridge/host/container/none&#xff0c;bridge為默認不需要用–net去指定&#xff0c;其他三種模式需要在創建容器時使用…

【力扣 - 最長連續數組】

題目描述 給定一個未排序的整數數組 nums &#xff0c;找出數字連續的最長序列&#xff08;不要求序列元素在原數組中連續&#xff09;的長度。 請你設計并實現時間復雜度為 O(n) 的算法解決此問題。 示例 1&#xff1a; 輸入&#xff1a;nums [100,4,200,1,3,2] 輸出&…

Linux命令:uniq命令和wc命令

目錄 1 uniq命令1.1 uniq簡介1.2說明1.3案例1、默認輸出2、輸出重復行3、比較一行中的部分字符4、忽略大小寫5、只顯示唯一的行 2.4 uniq和sort命令配合使用1、文本統計2、統計IP連接數并排序 2 wc命令2.1 wc簡介2.2 說明2.3 案例1、默認輸出2、輸出字節、字符數、單詞數 總結 …