一文解密C++中的多態(tài)機(jī)制
一.多態(tài)
1.多態(tài)的用處
眾所周知C++語(yǔ)言的三大特性:封裝、多態(tài)、繼承。其中多態(tài)就是去完成某個(gè)行為,但是會(huì)根據(jù)不同的對(duì)象產(chǎn)生不同的狀態(tài),所以叫多態(tài)。
2.多態(tài)的實(shí)現(xiàn)
在繼承中實(shí)現(xiàn)多態(tài)還需要兩個(gè)條件:
1.使用基類的指針或者引用來(lái)調(diào)用虛函數(shù)
2.必須在派生類對(duì)虛函數(shù)進(jìn)行重寫
代碼演示如下:
class A
{
public:
virtual void func()
{
cout << "A::func()" << endl;
}
};
class B : public A
{
public:
void func()
{
cout << "B::func()" << endl;
}
};
int main()
{
B b;
A& a = b;
a.func();
return 0;
}
3.虛函數(shù)
用virtual修飾的類成員函數(shù)叫做虛函數(shù),雖然與虛擬繼承用的是同一關(guān)鍵字但是兩者并無(wú)關(guān)聯(lián)。
virtual void func(){cout << "A::func()" << endl;}派生類的重寫:
重寫需要在派生類中編寫與基類相同的虛函數(shù):返回類型相同(協(xié)變除外)、函數(shù)名相同、參數(shù)相同(缺省值可不同),然后函數(shù)具體實(shí)現(xiàn)的不同,來(lái)完成多態(tài)。
協(xié)變
協(xié)變?cè)试S基類派生類虛函數(shù)的返回值不同,但是要求返回值是互為父/子類的指針或者引用。如下所示:
class A
{
public:
A(int a = 1)
:_a(a) {}
virtual A* func(int val = 0)
{
cout << val<< endl;
return new A;
}
private:
int _a;
};
class B : public A
{
public:
B(int b = 1)
:_b(b) {}
virtual B* func(int val = 1)
{
cout << val<< endl;
return new B;
}
private:
int _b;
};
int main()
{
B b;
A& a = b;
a.func();
return 0;
}
上圖中,如果返回的不是本身自己父子類的指針/引用,則可以交換順序!需要注意的是在派生類重寫基類的虛函數(shù)可以不加virtual
析構(gòu)函數(shù)的重寫
如果基類重寫的析構(gòu)函數(shù),在派生類可以不加virtual也可以完成重寫(因?yàn)榫幾g器將析構(gòu)函數(shù)的名稱統(tǒng)一處理成destructor。)
4.override 和 final
這兩個(gè)關(guān)鍵字都是C++11的新語(yǔ)法,final修飾虛函數(shù) 使得虛函數(shù)不可以重寫。
override 可以在派生類函數(shù)檢查是否重寫的基類虛函數(shù),如果沒(méi)有就 報(bào)錯(cuò)。
如果不想類被繼承可以采用:將構(gòu)造函數(shù)設(shè)為私有、將類用final修飾為最終類
5.重載重寫與重定義
重載:兩個(gè)函數(shù)在同一作用域、函數(shù)名/參數(shù)相同
重寫:兩個(gè)函數(shù)分別在基類和派生類的作用域、函數(shù)名/參數(shù)/返回值都必須相同(協(xié)變例外)、兩個(gè)函數(shù)必須是虛函數(shù)
隱藏(重定義)兩個(gè)函數(shù)分別在基類和派生類的作用域、函數(shù)名相同、兩個(gè)基類和派生類的同名函數(shù)不構(gòu)成重寫就是重定義
6.虛函數(shù)表
如果在類中定義了虛函數(shù),那么類中就會(huì)有個(gè)虛表用來(lái)存放虛表指針。
虛函數(shù)表本質(zhì)是一個(gè)存虛函數(shù)指針的指針數(shù)組
虛表中存放著虛函數(shù),同類型對(duì)象會(huì)共用一塊虛表。
子類自己的虛函數(shù)只會(huì)放到第一個(gè)父類的虛表后面,其他父類的虛表不需要存儲(chǔ),因?yàn)榇鎯?chǔ)了也不能調(diào)用
有虛函數(shù)的類前4/8字節(jié)存儲(chǔ)的是虛表的地址。
去虛表找 看是什么對(duì)象 (多態(tài)時(shí))
虛函數(shù)重寫只重寫函數(shù)的實(shí)現(xiàn) 缺省值會(huì)使用父類的
到此這篇關(guān)于一文解密C++中的多態(tài)機(jī)制的文章就介紹到這了,更多相關(guān)C++多態(tài)機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用C實(shí)現(xiàn)PHP擴(kuò)展 Image_Tool 圖片常用處理工具類的使用
該擴(kuò)展是基于ImageMagick基礎(chǔ)實(shí)現(xiàn)的,圖片操作調(diào)用的是ImageMagick API2013-04-04
VC++實(shí)現(xiàn)添加文件關(guān)聯(lián)的方法示例
這篇文章主要介紹了VC++實(shí)現(xiàn)添加文件關(guān)聯(lián)的方法,涉及VC++針對(duì)注冊(cè)表的寫入與VC事件響應(yīng)相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
Visual Studio Code運(yùn)行C++代碼時(shí)顯示CLOCKS_PER_SEC未定義的問(wèn)題及解決方法
這篇文章主要介紹了解決Visual Studio Code運(yùn)行C++代碼時(shí)顯示CLOCKS_PER_SEC未定義的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
C++通過(guò)控制臺(tái)訪問(wèn)deepseek接口并進(jìn)行對(duì)話
這篇文章主要為大家詳細(xì)介紹了C++如何通過(guò)控制臺(tái)訪問(wèn)deepseek接口并進(jìn)行對(duì)話,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
c++調(diào)用其他cpp文件的函數(shù)的幾種方式小結(jié)
本文介紹了在C++中將函數(shù)分類的方法,包括通過(guò)引入cpp文件和通過(guò)頭文件調(diào)用兩種方式,并詳細(xì)說(shuō)明了每種方式的實(shí)現(xiàn)步驟及過(guò)程,感興趣的可以了解一下2026-05-05
QT 實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能
本文介紹了如何使用QT技術(shù)實(shí)現(xiàn)一個(gè)具有動(dòng)態(tài)效果的隨機(jī)驗(yàn)證碼系統(tǒng),詳述了CaptchaMovableLabel和CaptchaLabel兩個(gè)自定義類的功能,包括顯示和拖動(dòng)字母、繪制噪音點(diǎn)和線條、以及隨機(jī)生成字母等,講解了如何通過(guò)繼承QWidget和QLabel來(lái)實(shí)現(xiàn)這些功能,并通過(guò)MainWindow創(chuàng)建界面2024-10-10
C語(yǔ)言動(dòng)態(tài)內(nèi)存管理malloc柔性數(shù)組示例詳解
這篇文章主要為大家介紹了C語(yǔ)言動(dòng)態(tài)內(nèi)存管理malloc柔性數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
C++實(shí)現(xiàn)銀行排隊(duì)系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)銀行排隊(duì)系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
C語(yǔ)言中_string.h庫(kù)函數(shù)功能及其用法詳解
在計(jì)算機(jī)編程中,字符串處理是一項(xiàng)常見(jiàn)而重要的任務(wù),C語(yǔ)言的string.h頭文件提供了一系列函數(shù)和工具,用于對(duì)字符串進(jìn)行操作和處理,本文將對(duì)string.h頭文件中的所有函數(shù)進(jìn)行全面介紹,包括它們的功能和使用方法,以幫助大家更好地理解和利用該頭文件2023-12-12
C++結(jié)構(gòu)體字節(jié)對(duì)齊示例
這篇文章主要為大家介紹了C++結(jié)構(gòu)體字節(jié)對(duì)齊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

