中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站怎么做白色字蘇州吳中區(qū)seo關(guān)鍵詞優(yōu)化排名

網(wǎng)站怎么做白色字,蘇州吳中區(qū)seo關(guān)鍵詞優(yōu)化排名,網(wǎng)上做兼職網(wǎng)站有哪些工作,天津哪家做企業(yè)網(wǎng)站今天我們來談?wù)凜的繼承與多態(tài)😊😊😊,本篇的關(guān)鍵內(nèi)容如下: 繼承的本質(zhì)及其原理派生類的構(gòu)造和析構(gòu)過程重載、隱藏和覆蓋類的向下或向上轉(zhuǎn)型靜態(tài)綁定與動(dòng)態(tài)綁定虛函數(shù)對類的影響虛析構(gòu)函數(shù) 下面,我們將對這…

今天我們來談?wù)凜++的繼承與多態(tài)😊😊😊,本篇的關(guān)鍵內(nèi)容如下:

  • 繼承的本質(zhì)及其原理
  • 派生類的構(gòu)造和析構(gòu)過程
  • 重載、隱藏和覆蓋
  • 類的向下或向上轉(zhuǎn)型
  • 靜態(tài)綁定與動(dòng)態(tài)綁定
  • 虛函數(shù)對類的影響
  • 虛析構(gòu)函數(shù)

下面,我們將對這幾個(gè)有關(guān)于C++繼承與多態(tài)的關(guān)鍵內(nèi)容進(jìn)行詳述的論述

淺談C++的繼承與多態(tài)

    • 一、繼承的本質(zhì)及其原理
    • 二、派生類的構(gòu)造和析構(gòu)過程
    • 三、重載、隱藏和覆蓋
    • 四、類的向下或向上轉(zhuǎn)型
    • 五、靜態(tài)綁定與動(dòng)態(tài)綁定
    • **一個(gè)問題:thinking::thinking::thinking::一個(gè)類聲明了虛函數(shù)后,當(dāng)調(diào)用該虛函數(shù)時(shí),一定是動(dòng)態(tài)綁定嗎?** **不一定 !**
    • 六、虛析構(gòu)函數(shù)
    • **什么時(shí)候把基類的析構(gòu)函數(shù)聲明為虛函數(shù)呢?**
    • 七、虛函數(shù)對類的影響

一、繼承的本質(zhì)及其原理

在C++中,繼承是一種面向?qū)ο缶幊趟枷氲母拍?#xff0c;允許一個(gè)類繼承另一個(gè)類的屬性和方法,同時(shí)也可以在此基礎(chǔ)上添加新的屬性和方法。究其本質(zhì),即:

  • 代碼的復(fù)用
  • 在基類中給所有派生類提供一個(gè)統(tǒng)一的接口,讓派生類重寫,滿足開閉原則

二、派生類的構(gòu)造和析構(gòu)過程

在定義的派生類中,由于派生類是從基類的基礎(chǔ)上繼承過來的,對應(yīng)繼承而來的成員的初始化和清理是由基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)負(fù)責(zé),而派生類的構(gòu)造和析構(gòu)函數(shù)則負(fù)責(zé)初始化和清理派生類中特定的部分,所以在派生類調(diào)用構(gòu)造函數(shù)需要初始化基類里的成員變量時(shí),不能直接指定,而是需要通過基類的構(gòu)造函數(shù)來進(jìn)行初始化,如下:

class Base
{
public:Base(int d) :ma(d) { cout << "Base()" << endl; }~Base() { cout << "~Base()" << endl; }
protected:int ma;
};class Derive :public Base
{
public://Derive(int d = 20) :ma(d), mb(d) {cout << "Derive()" << endl;}//此句會出現(xiàn)報(bào)錯(cuò):"ma" 不是類 "Derive" 的非靜態(tài)數(shù)據(jù)成員或基類Derive(int d = 20) :Base(d), mb(d) {cout << "Derive()" << endl;}~Derive() { cout << "~Derive()" << endl; }
private:int mb;
};

這里我們給出一段關(guān)于派生類構(gòu)造和析構(gòu)過程的主要描述:

  • 派生類調(diào)用基類的構(gòu)造函數(shù),初始化從基類繼承而來的成員
  • 調(diào)用派生類自己的構(gòu)造函數(shù),初始化派生類自己特有的成員
  • 調(diào)用派生類的析構(gòu)函數(shù),釋放派生類成員可能占用的外部資源(堆空間、文件等)
  • 調(diào)用基類的構(gòu)造函數(shù),釋放派生類內(nèi)存中從基類繼承而來的成員可以占用的外部資源(堆空間、文件等)
int main()
{Derive m(20);  //可以自己允許一遍,查看程序允許結(jié)果return 0;
}

三、重載、隱藏和覆蓋

重載: 一組函數(shù)重載,必須處在同一個(gè)作用域中,且函數(shù)名相同,參數(shù)列表不同
隱藏: 隱藏其實(shí)就是隱藏作用域,即,在繼承結(jié)構(gòu)中,派生類的同名成員,把基類的同名成員隱藏掉了
覆蓋: 如果派生類中定義的方法與在基類繼承而來的方法,在返回值、函數(shù)名、參數(shù)列表都相同的前提下,且基類的實(shí)現(xiàn)方法為virtual虛函數(shù),那么派生類的這個(gè)方法就會被自動(dòng)的處理成虛函數(shù),本質(zhì)上是虛函數(shù)表上的虛函數(shù)地址的覆蓋,詳見后文!

若我們在上面的Base類和Derive中添加方法 void show() ,在派生類調(diào)用show函數(shù)時(shí)會優(yōu)先在自己類中尋找對應(yīng)的函數(shù)方法,即會打印Derive::show(),基類的show方法被隱藏了

class Base
{...void show() { cout << "Base::show()" << endl; }...
};
class Derive :public Base
{void show() { cout << "Derive::show()" << endl; }...
};int main()
{Derive m(20);m.show();  //優(yōu)先找派生類自己show成員return 0;
}

四、類的向下或向上轉(zhuǎn)型

在C++中,派生類對象轉(zhuǎn)化為基類對象、基類對象轉(zhuǎn)化為派生類對象的情形可以描述為:

  • 向上轉(zhuǎn)型: 派生類對象(指針) -> 基類對象(指針) YES
  • 向下轉(zhuǎn)型: 基類對象(指針) -> 派生類對象(指針) NO

由于派生類是由基類繼承而來的,其給它分配地址空間大于基類的地址空間,故可以將派生類對象(指針)轉(zhuǎn)化為基類對象(指針),即Base* pb = &m,而不可以可以將基類類對象(指針)轉(zhuǎn)化為派生類對象(指針),即Derive* pd = &m;,如下圖所示:
在這里插入圖片描述
對于 派生類 -》 基類: 相當(dāng)于切片,紅色部分內(nèi)存在基類指針訪問不了,也不會被訪問
對于 基類 -》 派生類: 派生類申請的地址空間大于基類,一旦派生類對象/指針訪問紅色部分時(shí),由于基類對象是沒有這塊空間的,直接會發(fā)生非法訪問問題
在這里插入圖片描述

五、靜態(tài)綁定與動(dòng)態(tài)綁定

靜態(tài)綁定和動(dòng)態(tài)綁定是C++中兩種不同的綁定方式

  • 靜態(tài)綁定: 在編譯時(shí)進(jìn)行的綁定。它根據(jù)函數(shù)調(diào)用時(shí)的靜態(tài)類型來確定要調(diào)用的函數(shù)。靜態(tài)綁定適用于非虛函數(shù),它會默認(rèn)綁定到函數(shù)定義中的相應(yīng)代碼。
  • 動(dòng)態(tài)綁定: 在運(yùn)行時(shí)進(jìn)行的綁定。它根據(jù)函數(shù)調(diào)用時(shí)的動(dòng)態(tài)類型來確定要調(diào)用的函數(shù)。動(dòng)態(tài)綁定適用于虛函數(shù),它允許在運(yùn)行時(shí)根據(jù)實(shí)際對象類型來調(diào)用相應(yīng)的函數(shù)。這樣可以實(shí)現(xiàn)多態(tài)性,即不同對象調(diào)用同名函數(shù)時(shí)可以執(zhí)行不同的操作。
#include <iostream>class Base {
public:void print() {std::cout << "Base class" << std::endl;}virtual void display() {std::cout << "Base class" << std::endl;}
};class Derived : public Base {
public:void print() {std::cout << "Derived class" << std::endl;}void display() {std::cout << "Derived class" << std::endl;}
};int main() {Base* d = new Derived();d->print(); // 靜態(tài)綁定,調(diào)用Base類的print函數(shù)/*mov eax, dword ptr[pb]mov ecx, dword ptr[eax]call ecx;(虛函數(shù)地址)  動(dòng)態(tài)(運(yùn)行時(shí)期)的綁定(函數(shù)的調(diào)用)*/d->display(); // 動(dòng)態(tài)綁定,調(diào)用Derived類的display函數(shù)return 0;
}

d->print() 調(diào)用的是靜態(tài)綁定,因?yàn)?print() 函數(shù)在基類中不是虛函數(shù)。即使 d 指向的對象實(shí)際類型是 Derived 類,編譯器也會根據(jù)指針類型(Base*)來靜態(tài)綁定調(diào)用基類的 print() 函數(shù)。所以輸出為 Base class

d->display() 這里調(diào)用的是動(dòng)態(tài)綁定,因?yàn)?display() 函數(shù)是虛函數(shù)。在運(yùn)行時(shí),實(shí)際調(diào)用的是指向的對象的類型的版本,即RTTI (run-time type information) ,即 Derived 類中的 display() 函數(shù)。所以輸出為 Derived class

一個(gè)問題🤔🤔🤔:一個(gè)類聲明了虛函數(shù)后,當(dāng)調(diào)用該虛函數(shù)時(shí),一定是動(dòng)態(tài)綁定嗎? 不一定 !

動(dòng)態(tài)綁定的實(shí)現(xiàn)通常涉及虛函數(shù)表(vtable)的使用。每個(gè)包含虛函數(shù)的類都會有一個(gè)虛函數(shù)表,其中包含了指向虛函數(shù)的指針。子類會繼承父類的虛函數(shù)表,并在其自己的虛函數(shù)表中重寫父類的虛函數(shù)指針。這樣,當(dāng)通過指針或引用調(diào)用虛函數(shù)時(shí),會根據(jù)對象的實(shí)際類型找到對應(yīng)的虛函數(shù)指針,并調(diào)用正確的函數(shù)。
然而,如果直接通過對象調(diào)用虛函數(shù),編譯器會根據(jù)對象的靜態(tài)類型來進(jìn)行綁定,即根據(jù)對象的聲明類型來調(diào)用虛函數(shù),而這就是靜態(tài)綁定,因?yàn)榫幾g器在編譯時(shí)已經(jīng)確定了應(yīng)該調(diào)用哪個(gè)函數(shù),不需要在運(yùn)行時(shí)根據(jù)對象的實(shí)際類型進(jìn)行判斷。因此,在通過指針或引用調(diào)用虛函數(shù)時(shí),會進(jìn)行動(dòng)態(tài)綁定,根據(jù)對象的實(shí)際類型確定調(diào)用哪個(gè)函數(shù);而在直接通過對象調(diào)用虛函數(shù)時(shí),會進(jìn)行靜態(tài)綁定,根據(jù)對象的聲明類型確定調(diào)用哪個(gè)函數(shù)
在這里插入圖片描述

六、虛析構(gòu)函數(shù)

虛析構(gòu)函數(shù)是一種特殊的析構(gòu)函數(shù),用于實(shí)現(xiàn)多態(tài)性。它允許在基類指針指向派生類對象時(shí),使用基類指針來調(diào)用派生類對象的析構(gòu)函數(shù),從而正確地釋放派生類對象的資源,我們先來看看下面幾個(gè)問題

我們來看看虛函數(shù)所依賴的條件:

  • 虛函數(shù)能產(chǎn)生地址,存儲在vftable虛函數(shù)表中
  • 對象必須存在(vfptr -> vftable -> 虛函數(shù)地址)

哪些函數(shù)不能聲明為虛函數(shù)?

  • 構(gòu)造函數(shù):構(gòu)造函數(shù)在對象創(chuàng)建和銷毀的過程中是特殊的,在構(gòu)造函數(shù)中的所有函數(shù)都是靜態(tài)綁定的,不能聲明為virtual
  • 靜態(tài)成員函數(shù)static:虛函數(shù)是通過對象訪問的,而靜態(tài)成員函數(shù)沒有 this 指針,是直接通過類名訪問的,不能被繼承和覆蓋
  • 內(nèi)聯(lián)函數(shù):內(nèi)聯(lián)函數(shù)在編譯時(shí)會直接將函數(shù)體嵌入到函數(shù)調(diào)用點(diǎn),沒有函數(shù)調(diào)用的開銷。而虛函數(shù)是通過虛函數(shù)表來確定的,無法進(jìn)行內(nèi)聯(lián)

什么時(shí)候把基類的析構(gòu)函數(shù)聲明為虛函數(shù)呢?

當(dāng)基類指針(或引用)指向在堆上通過new創(chuàng)建的派生類對象時(shí),派生類對象也會分配一份外部空間。如果基類的析構(gòu)函數(shù)沒有聲明為虛函數(shù),在準(zhǔn)備使用delete刪除基類指針時(shí),會發(fā)生靜態(tài)綁定。這樣,基類對象會調(diào)用基類的析構(gòu)函數(shù),而派生類對象則無法調(diào)用其自己的析構(gòu)函數(shù),導(dǎo)致內(nèi)存泄漏。

class Base
{
public:Base(int d) :ma(d) { cout << "Base()" << endl; }~Base() { cout << "~Base()" << endl; }virtual void show() { cout << "Base::show()" << >endl; }
protected:int ma;
};class Derive :public Base
{
public:Derive(int d) :Base(d), mb(d), ptr(new int(d)){cout << "Derive()" << endl;}// 基類的析構(gòu)函數(shù)是virtual,那么派生類的析構(gòu)>函數(shù)自動(dòng)變成virtual~Derive(){delete ptr;cout << "~Derive()" << endl;}void show() { cout << "Derive::show()" << endl; }private:int mb;int* ptr;
};int main()
{Base* pb = new Derive(10);pb->show();delete pb;return 0;
}     

在將基類的析構(gòu)函數(shù)聲明為虛函數(shù)后,當(dāng)使用delete刪除基類指針時(shí),由于基類的析構(gòu)函數(shù)是虛函數(shù),會發(fā)生動(dòng)態(tài)綁定。這樣,派生類的析構(gòu)函數(shù)會自動(dòng)成為虛析構(gòu)函數(shù)。在執(zhí)行delete時(shí),通過虛函數(shù)表指針(vfptr)找到虛函數(shù)表(vftable),將基類在虛函數(shù)表上的虛析構(gòu)函數(shù)覆蓋為派生類的虛析構(gòu)函數(shù)。這樣就會先調(diào)用派生類的析構(gòu)函數(shù),再調(diào)用基類的虛構(gòu)函數(shù)進(jìn)行釋放。

七、虛函數(shù)對類的影響

  1. 一個(gè)類里面定義了虛函數(shù),那么編譯階段,編譯器會給這個(gè)類生成唯一的虛函數(shù)表 vftable 主要存放的是RTTI指針虛函數(shù)地址,當(dāng)程序運(yùn)行時(shí),每一張?zhí)摵瘮?shù)表都會加載到內(nèi)存的.rodate區(qū)(只讀,不能寫)

  2. 一個(gè)類中定義了虛函數(shù),那么這個(gè)類定義的對象在程序運(yùn)行時(shí),內(nèi)存中開始的部分多存儲一個(gè)vfptr虛函數(shù)指針,指向相同類型的虛函數(shù)表vftable,一個(gè)類型定義的n個(gè)對象,它們的 vfptr 指向的都是同一張?zhí)摵瘮?shù)表

  3. 一個(gè)類里的虛函數(shù)個(gè)數(shù),不影響對象內(nèi)存的大小(vfptr),影響的是虛函數(shù)表的大小

  4. 如果派生類中的方法和基類繼承而來的某個(gè)方法的返回值、函數(shù)名、參數(shù)列表相同,而基類的方法是virtual虛函數(shù),那么派生類的這個(gè)方法會自動(dòng)被處理成虛函數(shù),將虛函數(shù)表中的原來的虛函數(shù)地址覆蓋成派生類的虛函數(shù)地址


🌻🌻🌻以上就是有關(guān)淺淺談C++的繼承與多態(tài)(靜態(tài)綁定、動(dòng)態(tài)綁定和虛函數(shù)等)的內(nèi)容,如果聰明的你瀏覽到這篇文章并覺得文章內(nèi)容對你有幫助,請不吝動(dòng)動(dòng)手指,給博主一個(gè)小小的贊和收藏 🌻🌻🌻

http://www.risenshineclean.com/news/22053.html

相關(guān)文章:

  • 網(wǎng)站怎樣做seo成功營銷案例分享
  • 昆明網(wǎng)站做項(xiàng)目推廣平臺有哪些
  • 新手站長如何購買虛擬主機(jī)做網(wǎng)站seo對各類網(wǎng)站的作用
  • 哪個(gè)網(wǎng)站可以懸賞做圖宣傳推廣的十種方式
  • 國內(nèi)環(huán)保行業(yè)網(wǎng)站開發(fā)seo獨(dú)立站
  • 自己做的網(wǎng)站主頁打開速度上海百度分公司電話
  • 裝飾裝修網(wǎng)站建設(shè)方案做網(wǎng)絡(luò)銷售如何找客戶
  • crm辦公系統(tǒng)武漢關(guān)鍵詞seo
  • 建設(shè)網(wǎng)站學(xué)什么條件網(wǎng)站運(yùn)營和維護(hù)
  • 無法訪問WordPress二級馮耀宗seo
  • 那家專門做特賣的網(wǎng)站權(quán)威seo技術(shù)
  • 免費(fèi)網(wǎng)站空間可訪問小網(wǎng)站怎么搜關(guān)鍵詞
  • 做網(wǎng)站引流的最佳方法四川自助seo建站
  • 企業(yè)網(wǎng)站推廣的收獲與啟示軟件開發(fā)培訓(xùn)學(xué)校
  • 中國企業(yè)招聘網(wǎng)seo外鏈技巧
  • w網(wǎng)站開發(fā)文獻(xiàn)百度投訴中心在線申訴
  • 紹興優(yōu)秀做網(wǎng)站的蘇州網(wǎng)站維護(hù)
  • it行業(yè)做網(wǎng)站一個(gè)月多少錢中國推廣網(wǎng)站
  • 用ecshop的網(wǎng)站西地那非片能延時(shí)多久有副作用嗎
  • 網(wǎng)站推廣方案途徑網(wǎng)站設(shè)計(jì)公司怎么樣
  • ubuntu apache php mysql wordpress某個(gè)網(wǎng)站seo分析實(shí)例
  • 網(wǎng)頁設(shè)計(jì)站點(diǎn)規(guī)劃蘇州seo營銷
  • 免費(fèi)的網(wǎng)頁設(shè)計(jì)成品詳解seo黑帽教學(xué)網(wǎng)
  • 大連省建設(shè)廳網(wǎng)站seo研究中心教程
  • 網(wǎng)站建設(shè)企業(yè) 熊賬號aso優(yōu)化app推廣
  • 北京網(wǎng)站建設(shè)天下公司網(wǎng)絡(luò)推廣營銷方式
  • 如何在建設(shè)銀行網(wǎng)站查驗(yàn)回單全國免費(fèi)發(fā)布信息平臺
  • 做網(wǎng)站賺幾百萬媒體網(wǎng)站
  • wordpress添加搜索插件北京seo顧問服務(wù)
  • 本網(wǎng)站服務(wù)器設(shè)在美國服務(wù)器保護(hù)友情鏈接交易平臺源碼