一文學會c++繼承 組合

文章目錄

  • 繼承簡介
    • 定義
    • 訪問限定符和繼承方式
  • ?基類派生類賦值轉換
  • 繼承的作用域
  • 派生類的默認成員函數
  • 繼承與友元
  • 繼承與靜態成員
  • ?復雜的菱形繼承
    • 虛擬繼承
  • 組合

繼承簡介

繼承是面向對象程序設計代碼復用的重要手段,使得程序員可以在保持原類的基礎上擴展,新擴展的類叫派生類體現類的層級結構,之前的重載是函數復用,繼承是類的復用

定義

#include <iostream>
#include <string>
using namespace std;
class person
{
public:void print(){cout << _name << " " << _sex << " " << _age << endl;;}
protected:string _name ="Jack";string _sex ="man";int _age=18;
};
class student : public person
{
protected:int _number;
};
int main()
{person p1;student s1;p1.print();s1.print();return 0;
}

可以看到,student是派生類,public是繼承方式,person是基類
派生類擁有基類的所有成員

訪問限定符和繼承方式

在這里插入圖片描述

在這里插入圖片描述
總結
1,基類的private成員,無論什么繼承,派生類都不可見,但是成員還是繼承到了派生類中,但是語法限制了派生類訪問
2,基類的private在派生類不可見,要想突破限制,就用protected,在類外不可訪問,但在派生類可訪問,訪問限制符protected是為繼承準備的
3,觀察上面表格,可以發現兩個不同限定符,取范圍更小的,如protected和private 取private
4,class類默認繼承方式private,struct類默認public一般都寫出繼承方式的
5,一般都是public繼承,幾乎很少private/protected

?基類派生類賦值轉換

🚩 派生類對象可以賦值基類對象/基類引用/基類指針,這個過程叫切片,意為著把派生類那塊基類所有的切給基類,
🚩基類對象不能賦值給派生類
在這里插入圖片描述
如圖,派生可以賦值給基類,只不過 _number消失了

int main()student s2;person p2 = s2;person* pp2 = &s2;person& ppp2 = s2;student* ss2 = (student*)pp2;//這種強轉可以pp2 = &p2;//student* ss2 = (student*)pp2;//這種會越界訪問return 0;

繼承的作用域

class person
{
public:void print(){cout << "基類" << endl;}
};
class student : public person
{
public:void print(){cout << "派生類" << endl;}
};
int main()
{student s3;s3.print();s3.student::print();s3.person::print();return 0;
}

在這里插入圖片描述
1,基類和派生類都有獨立的作用域
🚩2,基類與派生類成員重名時,子類調用會直接跳過父類成員,這叫隱藏,也叫重定義,或者可用 類名::成員 訪問
🚩3,在一個作用域的重名叫重載兩個作用域重名叫隱藏
4,繼承體系最好不要定義重名成員

派生類的默認成員函數

1,派生類對象初始化先調用基類構造函數,若基類無默認構造函數,則要在初始化列表顯式調用,再調用自己的構造函數
2,構造,賦值,拷貝構造都是先調基類再調子類
3,析構先調子類再基類
在這里插入圖片描述

#include <iostream>
#include <string>
using namespace std;
class person
{
public:person(string name ="jack"):_name(name){cout << "person()" << endl;}person(const person& p1):_name(p1._name){cout << "person(& p1)" << endl;}person& operator=(const person& p1){cout << "operator(const person&p1)" << endl;if(this!=&p1){_name = p1._name;}return *this;}~person(){ }
protected:string _name;
};
class student : public person
{
public:student(const string name="peter", int number = 110):person(name),_number(number){cout << "student()" << endl;}student(const student& s):person(s),_number(s._number){cout << "student(student& s)" << endl;}student& operator=(const student& s){if (this != &s){person::operator= (s);_number = s._number;}cout << "operator=(const student &s)" << endl;return *this;}~student(){ }
protected:int _number;
};
int main()
{person p1("peter");student s1("jack", 11);student s2;s2 = s1;return 0;
}

在這里插入圖片描述

繼承與友元

友元不能繼承,父類的朋友不是我的朋友
所以父類友元不能訪問子類成員,除非子類也聲明友元

#include <iostream>
#include <string>
using namespace std;
class student;//聲明
class person {
public:friend void Display(const person& p, const student& s);
protected:string _name = "person";
};class student : public person {
public:friend void Display(const person& p, const student& s); // 子類也聲明為友元student(int num = 0) : _number(num) {}
protected:int _number; 
};void Display(const person& p, const student& s) {cout << p._name << endl;cout << s._number << endl; //  現在可以訪問(student 的友元)
}int main() {person p;student s(12345);Display(p, s);return 0;
}

繼承與靜態成員

🚩基類定義static靜態成員,則整個繼承體系只有一個這樣的成員,無論多少派生多少子類,只有這一個靜態成員

#include <iostream>
#include <string>
using namespace std;
class person
{
public:person() {++_count;}string _name;static int _count;
};
int person ::_count = 0;
class student:public person
{
public:student():person(){++_count;}
};
int main()
{student s;cout << person::_count<<endl;return 0;
}

2

?復雜的菱形繼承

單繼承:一個子類只有一個父類
在這里插入圖片描述
多繼承:一個子類有兩個及以上的父類
在這里插入圖片描述
菱形繼承:多繼承的一種
在這里插入圖片描述
下圖,可看出菱形繼承數據冗余二義性問題,有兩份person值
在這里插入圖片描述

#include <iostream>
#include <string>
using namespace std;
class person
{
public:string _name;
};
class student :public person
{
public:string _num;
};
class teacher :public person
{
public:string _id;
};
class assistant :public student, public teacher
{
public:string _majorcourse;
};
int main()
{assistant a;//a._name = "peter";//?不明確a.student::_name = "peter";//可以指明訪問,a.teacher::_name = "jack";return 0;
}

指明訪問解決了二義性,但數據冗余還是沒解決,

虛擬繼承

虛擬繼承解決了二義性和數據冗余問題,

class person
{
public:string _name;
};
class student :virtual public person
{
public:string _num;
};
class teacher :virtual public person
{
public:string _id;
};
class assistant :virtual public student, virtual public teacher
{
public:string _majorcourse;
};

原理:
在這里插入圖片描述
只存一個person,student和teacher中的person 存到assistant的地址偏移量,用時再跳過去找

注意
菱形虛擬繼承底層復雜,一般不設計多繼承,更不能設計菱形繼承

組合

繼承是 is-a關系
組合是 has-a關系

  • 繼承復用 基類對子類公布了成員細節,俗稱白箱復用,一定程度上破壞了封裝,且基類 改動對子類影響較大,子類和基類關聯性強耦合度高
  • 組合復用 被組合對象要求有良好接口,基類成員細節不可見,俗稱黑箱復用不破壞封裝關聯性低耦合度低

實戰中能用組合就用組合,耦合度低,代碼便于維護,不過有些情況就適合繼承多態也需要繼承實現,可以用繼承和組合就用組合

class car
{
protected:string _colour;string _num;
};class Benz :public car
{
public:void Drive(){cout << "奢華" << endl;}
};

繼承關系

class tire
{
public:string _brand;int _size;
};
class car {string _colour;string _num;//車牌tire _t;//輪胎
};

組合關系

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

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

相關文章

.Net下載共享文件夾中的文件

由于IIS站點權限等問題&#xff0c;總是沒找到處理辦法&#xff0c;所以改用外掛的winform的方式來下載共享文件&#xff08;也可以改為使用windows服務的方式&#xff09;。 前提需要先在資源管理器中登錄到共享文件夾&#xff0c;確保系統能訪問。 服務端代碼 (.NET后端) usi…

目標檢測數據集 - 眼睛瞳孔檢測數據集下載「包含COCO、YOLO兩種格式」

數據集介紹&#xff1a;眼睛瞳孔檢測數據集&#xff0c;真實采集高質量人臉眼部圖片數據&#xff0c;適用于人臉定位、人臉疾病如白內障等疾病的視覺檢測。數據標注標簽包括 eyepupil 瞳孔一 個缺陷類別&#xff1b;適用實際項目應用&#xff1a;眼睛瞳孔檢測項目&#xff0c;以…

Keil MDK-ARM V5.42a 完整安裝教程

文章目錄一、安裝前期準備二、Keil MDK-ARM 主程序安裝三、器件支持包&#xff08;Pack&#xff09;安裝四、許可證激活五、安裝驗證Keil MDK&#xff08;Microcontroller Development Kit&#xff09;是針對 Arm Cortex-M 系列微控制器的專業開發環境&#xff0c;集成了 μVis…

WPF中引用其他元素各種方法

在WPF中&#xff0c;引用其他元素的方式有多種&#xff0c;每種方式適用于不同場景&#xff0c;各有優缺點。除了x:Reference&#xff0c;常用的還有以下幾種&#xff1a; 一、ElementName 綁定&#xff08;最常用的XAML綁定方式&#xff09; 通過元素的x:Name屬性引用同一作用…

Python生成統計學公式

一元線性回歸模型 2.1回歸分析概述/25 一、回歸分析基本概念/25 二、總體回歸函數/27 三、隨機誤差項/29 四、樣本回歸函數/30 2.2 一元線性回歸模型的參數估計/32 一、參數估計的普通最小二乘法/32 二、擬合優度/35 2.3基本假設與普通最小二乘估計量的統計性質/36 一、一元線性…

網絡工程師--華為命令專題

一、交換機 交換機分類&#xff1a;1.根據交換方式劃分&#xff1a;&#xff08;1&#xff09;存儲轉發式交換&#xff08;Store and Forward&#xff09;&#xff08;2&#xff09;直通式交換&#xff08;Cut-through&#xff09;&#xff08;3&#xff09;碎片過濾式交換&…

判斷可編輯div的光標是否在最前面

要判斷一個可編輯div(contenteditable)中的光標是否位于最前面&#xff0c;可以使用以下幾種方法&#xff1a; 方法一&#xff1a;使用Selection和Range API function isCaretAtStart(div) {const selection window.getSelection();if (selection.rangeCount 0) return false…

【unity實戰】使用Unity程序化生成3D隨機地牢(附項目源碼)

最終效果 文章目錄最終效果前言1、理解程序生成的核心概念2、種子值的核心作用3、程序生成的實際應用4、主流程序生成技術概覽5、選擇合適的技術實戰1、素材2、生成一面墻變換矩陣數據3、渲染墻壁4、加點隨機不同的墻壁效果5、繪制四面墻壁4、在四個角落生成支柱5、生成地板6、…

多賬號管理方案:解析一款免Root的App分身工具

之前有小伙伴問阿燦有沒有可以軟件分身的免費軟件&#xff0c;后來阿燦找到了一款可以無限分身的app感覺很實用&#xff0c;只有10M大小 02軟件介紹說白了它能給各種app和游戲做分身&#xff0c;包括V信、qQ、某音、某付寶這些&#xff0c;而且支持最新的安卓15系統。每個分身…

(附源碼)基于PHP和Vue的網上購物平臺

內容摘要 內容摘要: 隨著互聯網技術的迅猛發展&#xff0c;網上購物已成為人們日常生活的重要組成部分。本文圍繞PHPVue技術棧構建的網上購物平臺展開研究&#xff0c;深入探討了該平臺的架構設計與實現細節。平臺前端采用Vue框架&#xff0c;利用其組件化開發和數據驅動的特性…

51單片機

中斷系統1.什么是中斷當CPU正在處理某件事的時候外界發生了緊急事件請求&#xff0c;要求CPU暫停當前的工作&#xff0c;轉而去處理這個緊急事件&#xff0c;處理完以后&#xff0c;再回到原來被中斷的地方&#xff0c;繼續原來的工作&#xff0c;這樣的過程稱為中斷2.為什么要…

前端開發:HTML(5)—— 表單

下面我們來學習表單。 目錄 什么是Web表單&#xff1f; 表單標簽 1.form標簽 2.輸入框 文本框和密碼框 單選框和復選框 1.單選框 2.復選框 3.按鈕 &#xff08;1&#xff09;普通按鈕 &#xff08;2&#xff09;提交按鈕 &#xff08;3&#xff09;重置按鈕 &#…

【YOLOv8改進 - C2f融合】C2f融合SFS-Conv(空間 - 頻率選擇卷積)提升特征多樣性,同時減少參數和計算量

YOLOv8目標檢測創新改進與實戰案例專欄 專欄目錄: YOLOv8有效改進系列及項目實戰目錄 包含卷積,主干 注意力,檢測頭等創新機制 以及 各種目標檢測分割項目實戰案例 專欄鏈接: YOLOv8基礎解析+創新改進+實戰案例 文章目錄 YOLOv8目標檢測創新改進與實戰案例專欄 介紹 摘要 文…

如何將照片從POCO手機傳輸到Mac電腦

將照片從POCO手機傳輸到Mac電腦可能會有些困難&#xff0c;因為與iPhone不同&#xff0c;POCO設備沒有原生的macOS支持。這常常讓用戶尋找簡單、有效的方法來移動圖片&#xff0c;同時避免丟失質量&#xff0c;節省時間&#xff0c;并避免復雜的軟件設置。如果你想知道如何將照…

最新教程 | CentOS 7 內網環境 Nginx + ECharts 頁面離線部署手冊(RPM 安裝方式)

&#x1f4c1; 一、準備階段&#xff08;在聯網電腦上完成&#xff09; 1.1 下載 Nginx 官方 RPM 安裝包 在聯網電腦瀏覽器中訪問 Nginx 官方穩定版本倉庫&#xff1a; &#x1f517; 地址&#xff1a;http://nginx.org/packages/centos/7/x86_64/ ??云盤&#xff1a;htt…

Redis 常用數據類型 (下)

文章目錄前言一 Hash 哈希1. Hash 相關命令hset 和 hgethexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyincrbyfloat2. Hash 命令小結3. Hash 內部編碼Hash 在緩存中的應用場景介紹緩存方式對比二、List 列表1. LIST總體介紹2. List 普通命令lpushlpushxrpushrpushxlrange…

Java Lambda表達式:簡潔高效的函數式編程

1 lambda表達式Lambda 表達式本質是一個匿名函數&#xff0c;用于把函數作為參數&#xff0c;傳入方法中&#xff0c;實現函數式編程風格。使用Lambda 表達式可以使代碼變的更加簡潔緊湊。語法格式&#xff1a;(parameters)-> expression 或 (parameters)->{ statements…

python中的集合

目錄 初識集合 集合的含義 集合的作用 集合的使用場景 集合的定義 集合的常用操作 元素的增加 函數add() 元素的刪除 函數remove() 函數clear() 函數pop() 集合的遍歷 for循環 while循環 初識集合 集合的含義 在pyrhon中&#xff0c;集合是一種內置的數據結構…

如何將普通HTTP API接口改造為MCP服務器

在現代微服務架構中&#xff0c;MCP&#xff08;Mesh Configuration Protocol&#xff09; 作為高效配置分發協議&#xff0c;正逐漸替代傳統HTTP API。本文將手把手教你如何將普通HTTP API升級為高性能MCP服務器。 為什么需要MCP&#xff1f; 傳統HTTP API在配置分發場景存在…

數據結構第8問:什么是樹?

樹 【本節僅描述樹的定義、術語以及相關性質】 定義 樹是由若干個結點組成的有限集合。具有如下特征&#xff1a; 有且僅有一個根結點&#xff1b;除根結點外&#xff0c;每個其它結點有且僅有一個直接的父結點&#xff1b;除根結點外&#xff0c;每個結點可以有零個或者多個子…