深度揭秘C++面向?qū)ο缶幊讨欣^承的核心概念
一.繼承
1.繼承與面向?qū)ο?/h3>
我們知道C語(yǔ)言是面向過(guò)程的編程語(yǔ)言,C++在C語(yǔ)言的基礎(chǔ)上進(jìn)化出了面向?qū)ο蟮哪P?。而繼承就是面向?qū)ο蟮闹匾獙傩浴@^承使得我們?cè)谝粋€(gè)基礎(chǔ)屬性上能夠加以拓展,用來(lái)描述很多具有相同基本屬性又各有不同的事務(wù)。
2.繼承方式訪問(wèn)權(quán)限
繼承方式與訪問(wèn)權(quán)限相同都有三種:public、private、protected繼承,再結(jié)合基類(lèi)的三種訪問(wèn)權(quán)限,在派生類(lèi)中就有九種不同的情況,可以總結(jié)為:基類(lèi)為私有的成員在派生類(lèi)一律不可見(jiàn),其余權(quán)限按照與繼承方式相比較小的來(lái)。
3.切片(賦值轉(zhuǎn)換)
在實(shí)際應(yīng)用場(chǎng)景中我們常用基類(lèi)代表幾種事務(wù)共同的基本屬性,派生類(lèi)用來(lái)代表自己獨(dú)特的屬性,這就會(huì)導(dǎo)致派生類(lèi)對(duì)象一定是包含父類(lèi)對(duì)象的,所以子類(lèi)對(duì)象可以賦給父類(lèi)對(duì)象/指針/引用,過(guò)程會(huì)將子類(lèi)中獨(dú)特屬性的成員切出,剩余賦給父類(lèi)對(duì)象,所以稱(chēng)為切片,不僅如此基類(lèi)的指針可以通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換賦值給派生類(lèi)的指針,代碼演示如下:
class Person { protected: string _name; string _sex; int _age; }; class Student : public Person { public: int _No; }; void Test() { Student sobj; // 子類(lèi)對(duì)象可以賦值給父類(lèi)對(duì)象/指針/引用 Person pobj = sobj; Person* pp = &sobj; Person& rp = sobj; // 基類(lèi)的指針可以通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換賦值給派生類(lèi)的指針 pp = &sobj; Student * ps1 = (Student*)pp; // 這種情況轉(zhuǎn)換時(shí)可以的。 ps1->_No = 10; pp = &pobj; Student* ps2 = (Student*)pp; // 這種情況轉(zhuǎn)換時(shí)雖然可以,但是會(huì)存在越界訪問(wèn)的問(wèn) ps2->_No = 10; } int main() { Test(); return 0; }
4.作用域
如果在基類(lèi)和派生類(lèi)定義了同名函數(shù)就會(huì)構(gòu)成隱藏/重定義,子類(lèi)成員將屏蔽父類(lèi)對(duì)同名成員的直接訪問(wèn),如下所示;
class A { public: A(int num = 0) :_num(num) {} void func() { cout << _num << endl; } private: int _num; }; class B : public A { public: B(int val = 1) :_val(val) {} void func() { cout << _val<< endl; } private: int _val; }; int main() { B b; b.func(); b.A::func(); return 0; }
5.默認(rèn)成員函數(shù)
繼承這里遵循著一個(gè)規(guī)則:構(gòu)造先父后子,析構(gòu)先子后父。因?yàn)榕缮?lèi)中一定包含基類(lèi)的對(duì)象所以派生類(lèi)的構(gòu)造函數(shù)必須調(diào)用基類(lèi)的構(gòu)造函數(shù)初始化基類(lèi)的那一部分成員,如果基類(lèi)沒(méi)有默認(rèn)的構(gòu)造函數(shù)(無(wú)參、全缺省、編譯器默認(rèn)生成),則必須在派生類(lèi)構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。
派生類(lèi)的拷貝構(gòu)造函數(shù)必須調(diào)用基類(lèi)的拷貝構(gòu)造完成基類(lèi)的拷貝初始化。
派生類(lèi)的operator=必須要調(diào)用基類(lèi)的operator=完成基類(lèi)的復(fù)制。
基類(lèi)的析構(gòu)函數(shù)調(diào)用后會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)函數(shù),不能在派生類(lèi)顯示調(diào)用不然無(wú)法保證析構(gòu)先子后父的順序。
6.友元與靜態(tài)函數(shù)
友元關(guān)系不會(huì)繼承,靜態(tài)函數(shù)不會(huì)多次實(shí)例化。
7.解決菱形繼承的二義性與數(shù)據(jù)冗余
菱形繼承是多繼承的一種特殊情況,我們?cè)诰帉?xiě)代碼時(shí)應(yīng)要避免菱形繼承:
如上圖所示就是一個(gè)菱形繼承,這樣會(huì)導(dǎo)致A類(lèi)中會(huì)有兩份P類(lèi)中的成員,這樣不僅會(huì)浪費(fèi)空間,而且會(huì)產(chǎn)生二義性,如果我通過(guò)A對(duì)象訪問(wèn)P中的成員,因?yàn)锳類(lèi)中有兩份P中的成員所有會(huì)有歧義。為了解決此問(wèn)題,出現(xiàn)了虛擬繼承。如下圖所示:
那虛繼承是如何完成的呢:在d類(lèi)中建立虛基表,將原來(lái)冗余的對(duì)象放在d對(duì)象空間最下面,B、C原來(lái)存儲(chǔ)A的位置存儲(chǔ)當(dāng)前位置與空間最下面A對(duì)象的偏移量,保證指定B或者C對(duì)象訪問(wèn)_a時(shí)都能訪問(wèn)到。
8.繼承與組合
與繼承相比組合的耦合度更低,更適合我們使用!繼承又稱(chēng)為白箱復(fù)用,組合稱(chēng)為黑盒復(fù)用,因?yàn)槭褂媒M合的話是無(wú)法看到類(lèi)內(nèi)部的設(shè)計(jì)。
到此這篇關(guān)于深度揭秘C++面向?qū)ο缶幊讨欣^承的核心概念的文章就介紹到這了,更多相關(guān)C++繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++17文件系統(tǒng)庫(kù)之std::filesystem 示例詳解
std::filesystem是C++17引入的一個(gè)強(qiáng)大且易用的文件系統(tǒng)操作庫(kù),它提供了跨平臺(tái)的文件系統(tǒng)操作接口,簡(jiǎn)化了文件和目錄操作的代碼實(shí)現(xiàn),本文給大家介紹C++17文件系統(tǒng)庫(kù)之std::filesystem 示例詳解,感興趣的朋友一起看看吧2025-03-03C++實(shí)現(xiàn)LeetCode(60.序列排序)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(60.序列排序),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++實(shí)現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的數(shù)學(xué)算法
這篇文章和大家分享一下我個(gè)人對(duì)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的想法,目前暫時(shí)更新只整數(shù)十進(jìn)制的轉(zhuǎn)換,后續(xù)會(huì)更新帶有小數(shù)的進(jìn)制轉(zhuǎn)換,代碼使用c++實(shí)現(xiàn)2021-09-09C語(yǔ)言詳解格式控制符scanf與printf的輸入輸出
這篇文章主要介紹了C語(yǔ)言格式控制符中輸入scanf()和輸出printf()的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2022-04-04C++無(wú)痛實(shí)現(xiàn)日期類(lèi)的示例代碼
凡是要寫(xiě)類(lèi)必須要提到六大默認(rèn)成員(六位大爺):構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值重載函數(shù)、取地址重載函數(shù)(包括const對(duì)象和普通對(duì)象);那么這次的日期類(lèi)又需要伺候哪幾位大爺呢?本文就來(lái)詳細(xì)說(shuō)說(shuō)2022-10-10C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼
本文主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02