国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20)

這篇具有很好參考價值的文章主要介紹了【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

前言

大家好吖,歡迎來到 YY 滴C++系列 ,熱烈歡迎! 本章主要內(nèi)容面向接觸過C++的老鐵
主要內(nèi)容含:
【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言

歡迎訂閱 YY滴C++專欄!更多干貨持續(xù)更新!以下是傳送門!

  • YY的《C++》專欄
  • YY的《C++11》專欄
  • YY的《Linux》專欄
  • YY的《數(shù)據(jù)結(jié)構(gòu)》專欄
  • YY的《C語言基礎(chǔ)》專欄
  • YY的《初學(xué)者易錯點(diǎn)》專欄
  • YY的《小小知識點(diǎn)》專欄

一.繼承&復(fù)用&組合的區(qū)別

1)函數(shù)復(fù)用與繼承區(qū)別

函數(shù)復(fù)用與繼承區(qū)別:

  • 繼承(inheritance)機(jī)制是面向?qū)ο蟪绦蛟O(shè)計使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能, 這樣產(chǎn)生新的類,稱派生類 。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計的層次結(jié)構(gòu),體現(xiàn)了由簡單到復(fù)雜的認(rèn)知過程。以前我們接觸的復(fù)用都是函數(shù)復(fù)用,繼承是類 設(shè)計層次 的復(fù)用。

2)復(fù)用的分類

組合與繼承:

  • public繼承是一種is-a的關(guān)系。也就是說每個派生類對象 都是一個基類對象:相當(dāng)于[人]與[學(xué)生]&[老師]的關(guān)系
  • 組合是一種has-a的關(guān)系。假設(shè)B組合了A,每個B對象中 都有一個A對象:相當(dāng)于[手]與[人]的關(guān)系
  • 優(yōu)先使用對象組合,而不是類繼承
  • 實(shí)際盡量多去用組合。組合的耦合度低,代碼維護(hù)性好。不過繼承也有用武之地的,有
    些關(guān)系就適合繼承那就用繼承,另外要實(shí)現(xiàn)多態(tài),也必須要繼承。類之間的關(guān)系可以用
    繼承,可以用組合,就用組合

[1]白箱復(fù)用——繼承

  • 繼承允許你根據(jù)基類的實(shí)現(xiàn)來定義派生類的實(shí)現(xiàn)。這種通過生成派生類的復(fù)用通常被稱 為白箱復(fù)用(white-box reuse)。術(shù)語“白箱”是相對可視性而言:在繼承方式中,基類的 內(nèi)部細(xì)節(jié)對子類可見。 繼承一定程度破壞了基類的封裝 ,基類的改變,對派生類有很 大的影響。派生類和基類間的依賴關(guān)系很強(qiáng), 耦合度高。

[2]黑箱復(fù)用——組合(優(yōu)先)

  • 對象組合是類繼承之外的另一種復(fù)用選擇。新的更復(fù)雜的功能可以通過組裝或組合對象來獲得。 對象組合要求被組合的對象具有良好定義的接口。這種復(fù)用風(fēng)格被稱為 黑箱復(fù)用(black-box reuse),因?yàn)閷ο蟮膬?nèi)部細(xì)節(jié)是不可見的。對象只以“黑箱”的形式出現(xiàn)。組合類之間沒有很強(qiáng)的依賴關(guān)系,耦合度低。優(yōu)先使用對象組合有助于你保持每個類被封裝.

二.繼承的基本格式與繼承以后的訪問方式變化(基類成員)

1)基本格式

【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言

2)三種繼承方式

  • 繼承方式分為三種:public繼承,protect繼承,private繼承
  • 保護(hù)訪問限定符專門為繼承而產(chǎn)生:基類private成員在派生類中是不能被訪問 ,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為 protected ??梢钥闯霰Wo(hù)成員限定符是因繼承才出現(xiàn)的。

3)在派生類中不可見

  • 基類private成員在派生類中無論以什么方式繼承都是 不可見的 。這里的不可見是指基類的私有成員還是被繼承到了派生類對象中,但是語法上限制派生類對象不管在類里面還是類外面都不能去訪問它。
  • 基類的保護(hù)成員 在派生類中仍然是保護(hù)成員,也無法通過派生類的對象來直接訪問。

4)基類成員經(jīng)過不同繼承以后分別到派生類的什么作用域中【訪問方式變化】

記憶與理解:

  1. 權(quán)限大?。簆ublic > protect > private
  2. 基類中的public成員,經(jīng)過什么繼承,就到派生域的什么作用域中
  3. 【以權(quán)限小的為主】基類中的protect成員,權(quán)限小于public:經(jīng)過public繼承還是到protect作用域中,其權(quán)限又大于private,繼承,經(jīng)過private繼承后到private作用域中
  4. 基類中的private成員,經(jīng)過任何繼承都在派生類中不可見
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言

5)struct和class的默認(rèn)繼承方式

  • 使用關(guān)鍵字class時默認(rèn)的繼承方式是private
  • 使用struct時默認(rèn)的繼承方式是public
  • 不過最好顯示的寫出繼承方式

6)實(shí)際運(yùn)用中一般使用都是public繼承的原因

  • 在實(shí)際運(yùn)用中一般使用都是public繼承,幾乎很少使用protetced/private繼承,也不提倡使用protetced/private繼承, 因?yàn)閜rotetced/private繼承下來的成員都只能在派生類的類里面使用 ,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng)

三.基類和派生類對象賦值轉(zhuǎn)換【切片概念】

  • 派生類對象 可以賦值給 基類的對象 / 基類的指針 / 基類的引用。這里有個形象的說法叫切片
    或者切割。寓意 把派生類中父類那部分 切來賦值過去
  • 基類對象不能賦值給派生類對象
  • 基類的指針或者引用可以通過 強(qiáng)制類型轉(zhuǎn)換 賦值給派生類的指針或者引用。但是必須是基類的指針是指向派生類對象時才是安全的
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言
class Person
{
protected :
 string _name; // 姓名
    string _sex;  // 性別
    int _age; // 年齡
};
class Student : public Person
{
public :
 int _No ; // 學(xué)號
};
void Test ()
{
 Student sobj ;
 // 1.子類對象可以賦值給父類對象/指針/引用
 Person pobj = sobj ;
 Person* pp = &sobj;
 Person& rp = sobj;
    
 //2.基類對象不能賦值給派生類對象
    sobj = pobj;
    
    // 3.基類的指針可以通過強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針
    pp = &sobj
    Student* ps1 = (Student*)pp; // 這種情況轉(zhuǎn)換時可以的。
    ps1->_No = 10;
    
    pp = &pobj;
 Student* ps2 = (Student*)pp; // 這種情況轉(zhuǎn)換時雖然可以,但是會存在越界訪問的問題
    ps2->_No = 10;
}

四.繼承中的【隱藏】

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

五.派生類的默認(rèn)成員函數(shù)生成機(jī)制

6個默認(rèn)成員函數(shù),“默認(rèn)”的意思就是指我們不寫,編譯器會變我們自動生成一個,那么在派生類
中,這幾個成員函數(shù)是如何生成的呢?文章來源地址http://www.zghlxwxcb.cn/news/detail-791114.html

  1. 派生類的構(gòu)造函數(shù)必須調(diào)用 基類 的構(gòu)造函數(shù)初始化基類的那一部分成員。如果基類沒有默認(rèn)的構(gòu)造函數(shù),則必須在派生類構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。
  2. 派生類的拷貝構(gòu)造函數(shù)必須調(diào)用 基類 的拷貝構(gòu)造完成基類的拷貝初始化。
  3. 派生類的operator=必須要調(diào)用 基類 的operator=完成基類的復(fù)制。
  4. 派生類的析構(gòu)函數(shù)會在被調(diào)用完成后自動調(diào)用 基類 的析構(gòu)函數(shù)清理基類成員。因?yàn)檫@樣才能 保證派生類對象先清理派生類成員再清理基類成員的順序。
  5. 派生類對象初始化先調(diào)用 基類 構(gòu)造再調(diào)派生類構(gòu)造。
  6. 派生類對象析構(gòu)清理先調(diào)用派生類析構(gòu)再調(diào) 基類 的析構(gòu)。
  7. 因?yàn)楹罄m(xù)一些場景析構(gòu)函數(shù)需要構(gòu)成重寫,重寫的條件之一是函數(shù)名相同(多態(tài)的條件)。【那么編譯器會對析構(gòu)函數(shù)名進(jìn)行特殊處理,處理成destrutor(),所以父類析構(gòu)函數(shù)不加virtual的情況下,子類析構(gòu)函數(shù)和父類析構(gòu)函數(shù)構(gòu)成隱藏關(guān)系】

六.“友元關(guān)系”不能被繼承

  • 友元關(guān)系不能繼承,也就是說基類友元不能訪問子類 私有 保護(hù) 成員
//fail
class Student;
class Person
{
public:
 friend void Display(const Person& p, const Student& s);
protected:
 string _name; // 姓名
};
class Student : public Person
{
protected:
 int _stuNum; // 學(xué)號
};
void Display(const Person& p, const Student& s)
{
 cout << p._name << endl;
 cout << s._stuNum << endl;
}
void main()
{
 Person p;
 Student s;
 Display(p, s);
}

七.基類定義了static靜態(tài)成員,整個繼承體系里面只有一個這樣的成員

  • 基類定義了static靜態(tài)成員,則整個繼承體系里面 只有一個 這樣的成員——即無論派生出多少個子類,都只有一個static成員實(shí)例
class Person
{
public :
 Person () {++ _count ;}                 //派生類會調(diào)用基類的構(gòu)造
protected :
 string _name ; // 姓名
public :
 static int _count; // 統(tǒng)計人的個數(shù)。
};
int Person :: _count = 0;
class Student : public Person
{
protected :
 int _stuNum ; // 學(xué)號
};
class Graduate : public Student
{
protected :
 string _seminarCourse ; // 研究科目
};
void TestPerson()
{
 Student s1 ;
 Student s2 ;
 Student s3 ;
 Graduate s4 ;
 cout <<" 人數(shù) :"<< Person ::_count << endl;  //輸出結(jié)果為4
 Student ::_count = 0;                   
 cout <<" 人數(shù) :"<< Person ::_count << endl;  //輸出結(jié)果為0
}

八.復(fù)雜的菱形繼承及菱形虛擬繼承

1)菱形繼承

  • 在面向?qū)ο笾?,常常存在這樣的事情,一個派生類它有兩個或兩個以上的基類,這種行為稱作多重繼承,示意圖如下:
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言
  • 在多重繼承的基礎(chǔ)上,Class Student 和Class Teacher 存在同名數(shù)據(jù)成員,則對Class Person而言這個同名的數(shù)據(jù)成員容易產(chǎn)生 二義性問題
  • 菱形繼承還會產(chǎn)生 數(shù)據(jù)冗余 現(xiàn)象;在Assistant的對象中Person成員會有兩份;
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言
class Person
{
public :
 string _name ; // 姓名
};
class Student : public Person
{
protected :
 int _num ; //學(xué)號
};
class Teacher : public Person
{
protected :
 int _id ; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected :
 string _majorCourse ; // 主修課程
};
void Test ()
{
 // 這樣會有二義性無法明確知道訪問的是哪一個
 Assistant a ;
a._name = "peter";
// 需要顯示指定訪問哪個父類的成員可以解決二義性問題,但是數(shù)據(jù)冗余問題無法解決
 a.Student::_name = "xxx";
 a.Teacher::_name = "yyy";
}

2)解決菱形繼承問題方法:虛擬繼承

  • 虛擬繼承 可以解決菱形繼承的二義性和數(shù)據(jù)冗余的問題。如下圖代碼中 在繼承關(guān)系前加上“virtual” ,在Student和Teacher的繼承Person時使用虛擬繼承,即可解決問題。
  • 需要注意的是,虛擬繼承不要在其他地方去使用。
class Person
{
public :
 string _name ; // 姓名
};
class Student : virtual public Person                  //虛擬繼承
{
protected :
 int _num ; //學(xué)號
};
class Teacher : virtual public Person                   //虛擬繼承
{
protected :
 int _id ; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected :
 string _majorCourse ; // 主修課程
};
void Test ()
{
 Assistant a ;
 a._name = "peter";
}

3)虛擬繼承解決菱形繼承原理————虛基表&虛基表指針&利用偏移量

【1】虛擬繼承前后的內(nèi)存模型變化

  • 虛擬繼承前:
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言
  • 虛擬繼承后:
    【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20),YY 滴 《C++系列》,c++,開發(fā)語言
  • 這里可以分析出D對象中將A放到的了 對象組成的最下面 ,這個A同時屬于B和C,那么B和C如何去找到公共的A呢?這里是通過了B和C的兩個指針,指向的一張表。這兩個指針叫 虛基表指針 ,這兩個表叫 虛基表 。虛基表中存的 偏移量 。通過偏移量可以找到下面的A。

到了這里,關(guān)于【C++】萬字一文全解【繼承】及其特性__[剖析底層化繁為簡](20)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C++干貨鋪】剖析string | 底層實(shí)現(xiàn)

    ========================================================================= 個人主頁點(diǎn)擊直達(dá): 小白不是程序媛 C++專欄: C++干貨鋪 代碼倉庫: Gitee ========================================================================= 目錄 成員變量 成員函數(shù) 構(gòu)造和拷貝構(gòu)造 賦值重載 析構(gòu)函數(shù) operator[ ] size 迭代器? rese

    2024年02月05日
    瀏覽(22)
  • C++三大特性—繼承“復(fù)雜的菱形繼承及菱形虛擬繼承”

    C++三大特性—繼承“復(fù)雜的菱形繼承及菱形虛擬繼承”

    C++的一個大坑:菱形繼承 希望這篇文章能讓你理解什么是菱形繼承,以及菱形繼承的注意事項(xiàng) 單繼承:一個子類只有一個直接父類時稱這個繼承關(guān)系為單繼承 多繼承:一個子類有兩個或以上直接父類時稱這個繼承關(guān)系為多繼承 ?java語言不支持多繼承,只支持單繼承。 菱形

    2024年02月03日
    瀏覽(15)
  • C++三大特性之一:繼承

    C++三大特性之一:繼承

    C++三大特性:繼承、多態(tài)和封裝。繼承是面向?qū)ο缶幊痰囊粋€核心概念,它允許我們根據(jù)一個已存在的類(基類或者叫父類),創(chuàng)建一個新的類(派生類或者叫子類),這個新的類繼承了類的屬性和行為。 1.繼承格式。 class 子類名 :繼承屬性(publicprotectedprivate)父類名{

    2024年04月25日
    瀏覽(26)
  • C++ 面向?qū)ο笕筇匦浴^承

    C++ 面向?qū)ο笕筇匦浴^承

    ?1主頁:我的代碼愛吃辣 ??2知識講解:C++ 繼承 ??3開發(fā)環(huán)境:Visual Studio 2022 ??4前言:面向?qū)ο笕筇匦缘?,封裝,繼承,多態(tài),今天我們研究研究 C++的繼承 。 目錄 一.繼承的概念及定義 1.繼承的概念 ?2.繼承的定義 二. 繼承關(guān)系和訪問限定符 ?三.基類和派生類對象賦

    2024年02月12日
    瀏覽(23)
  • 【C++】三大特性 --- 繼承的詳細(xì)講解

    【C++】三大特性 --- 繼承的詳細(xì)講解

    目錄 1.繼承的概念及定義 1.1 繼承的概念 1.2 繼承定義 1.2.1定義格式 1.2.2繼承關(guān)系和訪問限定符 1.2.3繼承基類成員訪問方式的變化 2.基類和派生類對象賦值轉(zhuǎn)換 3.繼承中的作用域 4.派生類的默認(rèn)成員函數(shù) 5.繼承與友元 6.繼承與靜態(tài)成員 7.復(fù)雜的菱形繼承及菱形虛擬繼承 8.繼承的

    2024年02月05日
    瀏覽(21)
  • 【C++入門】STL容器--vector底層數(shù)據(jù)結(jié)構(gòu)剖析

    【C++入門】STL容器--vector底層數(shù)據(jù)結(jié)構(gòu)剖析

    目錄 ?前言 ?1. vector的使用 ? ? ??vector的構(gòu)造 ?vector迭代器 ?vector空間相關(guān)的接口 ?vector 功能型接口 ?find ?swap ?insert ?erase 2. vector內(nèi)部數(shù)據(jù)結(jié)構(gòu)剖析 reserve ?push_back和pop_back size、capacity、empty、operator[ ]; ?insert和erase resize swap ?拷貝構(gòu)造和賦值重載 構(gòu)造函數(shù)補(bǔ)充 ?迭代器

    2024年01月25日
    瀏覽(22)
  • C++中菱形繼承中的多態(tài)在底層是如何實(shí)現(xiàn)的。

    C++中菱形繼承中的多態(tài)在底層是如何實(shí)現(xiàn)的。

    如果還不了解菱形繼承和多態(tài)的底層可以看這兩篇文章: C++中多態(tài)的底層實(shí)現(xiàn)_Qianxueban的博客-CSDN博客 C++的繼承以及virtual的底層實(shí)現(xiàn)_Qianxueban的博客-CSDN博客

    2024年02月09日
    瀏覽(18)
  • 【C++】一文帶你吃透C++繼承

    【C++】一文帶你吃透C++繼承

    ?? 博客主頁:??@披星戴月的賈維斯 ?? 歡迎關(guān)注:??點(diǎn)贊??收藏??留言 ??系列專欄:?? C/C++專欄 ??那些看似波瀾不驚的日復(fù)一日,一定會在某一天讓你看見堅持的意義!?? ??一起加油,去追尋、去成為更好的自己! 提示:以下是本篇文章正文內(nèi)容,下面案例可供參

    2024年02月07日
    瀏覽(663)
  • C++繼承(2)——賦值轉(zhuǎn)換、隱藏特性以及作用域

    C++繼承(2)——賦值轉(zhuǎn)換、隱藏特性以及作用域

    一.子類和父類對象的賦值轉(zhuǎn)換 子類對象賦值父類對象的另外兩種方式: 總結(jié): 二.父類與子類的作用域 1. 在繼承體系中基類和派生類都有獨(dú)立的作用域。 ????????例: 2.作用域練習(xí) ? ? ? ? 練習(xí)1: 解決方法: 先來看一個案例:變量間的賦值 ????????在上面這個代碼

    2024年02月14日
    瀏覽(18)
  • 【C++】:STL源碼剖析之vector類容器的底層模擬實(shí)現(xiàn)

    【C++】:STL源碼剖析之vector類容器的底層模擬實(shí)現(xiàn)

    構(gòu)造一個空vector size和capacity為0 將_start _finish _endofstorage 都置為空指針即可 傳統(tǒng)寫法 : 1). 新開辟一塊和 v 同樣容量的空間,更新 _start, _finish, _endofstorage 2). 將 v 中的數(shù)據(jù)拷貝到新開辟的空間中 注意 : 不要使用memcpy函數(shù)拷貝數(shù)據(jù),如果數(shù)據(jù)是內(nèi)置類型或淺拷貝的自定義類型

    2024年02月04日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包