C++深入探究重載重寫(xiě)覆蓋的區(qū)別
基類(lèi)實(shí)現(xiàn)
我們先實(shí)現(xiàn)一個(gè)基類(lèi)
class BaseTest
{
private:
virtual void display() { cout << "Base display" << endl; }
void say() { cout << "Base say()" << endl; }
public:
virtual void func() { cout << "Base func()" << endl; }
void exec()
{
display();
say();
}
void f1(string a) { cout << "Base f1(string)" << endl; }
void f1(int a) { cout << "Base f1(int)" << endl; }
void exec2()
{
display();
say();
}
};BaseTest類(lèi)中我們實(shí)現(xiàn)了一個(gè)虛函數(shù)display和 func。
BaseTest類(lèi)內(nèi)部重載了f1函數(shù),實(shí)現(xiàn)了兩個(gè)版本,一個(gè)參數(shù)為string一個(gè)參數(shù)為int。
同一個(gè)類(lèi)中的多個(gè)同名函數(shù)叫做重載。
實(shí)現(xiàn)了普通函數(shù)say,exec以及exec2函數(shù)。exec和exec2函數(shù)內(nèi)部調(diào)用了display和say函數(shù)。
子類(lèi)實(shí)現(xiàn)
子類(lèi)DeriveA繼承了基類(lèi)
class DeriveA : public BaseTest
{
public:
void display() { cout << "DeriveA display()" << endl; }
void f1(int a, int b) { cout << "DeriveA f1(int,int)" << endl; }
void say() { cout << "DeriveA say()" << endl; }
virtual void func() { cout << "DeriveA func()" << endl; }
void use_base_f1(int a, int b)
{
BaseTest::f1(2);
BaseTest::f1("test");
cout << "DeriveA f1(int, int)" << endl;
}
void exec2()
{
display();
say();
}
};
子類(lèi)DeriveA 子類(lèi)重新實(shí)現(xiàn)了display和func函數(shù),子類(lèi)重新實(shí)現(xiàn)父類(lèi)的虛函數(shù),叫做重寫(xiě)。
同樣子類(lèi)重新實(shí)現(xiàn)了f1和say函數(shù),由于父類(lèi)有f1和say,所以子類(lèi)重新實(shí)現(xiàn)覆蓋了父類(lèi)的函數(shù),
這種普通函數(shù)被子類(lèi)重寫(xiě)導(dǎo)致父類(lèi)的函數(shù)被隱藏了,叫做覆蓋。
函數(shù)調(diào)用
接下來(lái)我們通過(guò)函數(shù)調(diào)用,看一下覆蓋,重載和重寫(xiě)的區(qū)別
void derive_base_test1()
{
DeriveA a;
BaseTest *b = &a;
shared_ptr<BaseTest> c = make_shared<BaseTest>();
//輸出DeriveA func()
b->func();
//輸出DeriveA func()
a.func();
//輸出Base f1(string)
b->f1("abc");
//輸出Base f1(int)
b->f1(3);
//輸出DeriveA f1(int,int)
a.f1(3, 5);
a.use_base_f1(2, 4);
cout << "========================" << endl;
//輸出DeriveA display()
//輸出Base say()
b->exec();
//輸出DeriveA display()
//輸出Base say()
a.exec();
//輸出Base display
//輸出Base say()
c->exec();
cout << "======================== \n"
<< endl;
//輸出 DeriveA display()
//輸出 Base say()
b->exec2();
//輸出 DeriveA display()
//輸出 DeriveA say()
a.exec2();
//輸出 Base display
//輸出 Base say()
c->exec2();
}代碼里我們生成了一個(gè)DeriveA的實(shí)例a, 并將該實(shí)例返回給基類(lèi)BaseTest的指針b,所以:
1 b->func();會(huì)根據(jù)多態(tài)的效果調(diào)用子類(lèi)DeriveA的func函數(shù)
2 a.func() 因?yàn)閍是一個(gè)對(duì)象,所以調(diào)用子類(lèi)DeriveA的func函數(shù)
3 b->f1(“abc”) 調(diào)用基類(lèi)BaseTest的f1,因?yàn)閒1是一個(gè)普通函數(shù)
4 a.f1(3, 5) 調(diào)用DeriveA的f1,因?yàn)閍是一個(gè)普通對(duì)象。
5 當(dāng)我們想在子類(lèi)里調(diào)用基類(lèi)的f1函數(shù),可以通過(guò)基類(lèi)作用域加函數(shù)名的方式,比如例子中的
a.use_base_f1就在函數(shù)內(nèi)部通過(guò)BaseTest::f1調(diào)用了基類(lèi)函數(shù)f1
6 b->exec,首先b是一個(gè)指針且exec為普通函數(shù)只在基類(lèi)實(shí)現(xiàn)了,所以調(diào)用基類(lèi)的exec,
但是exec內(nèi)部調(diào)用了虛函數(shù)display,此時(shí)觸發(fā)多態(tài)機(jī)制調(diào)用DeriveA的display函數(shù),因?yàn)閎是一個(gè)指向子類(lèi)DeriveA對(duì)象的基類(lèi)BaseTest指針,exec內(nèi)部調(diào)用了普通函數(shù)display,因?yàn)閐isplay不是虛函數(shù),所以調(diào)用BaseTest的display函數(shù)
7 a.exec(); a是一個(gè)DeriveA對(duì)象,DeriveA自己沒(méi)有實(shí)現(xiàn)exec函數(shù),所以調(diào)用基類(lèi)BaseTest的exec函數(shù),exec內(nèi)部調(diào)用display虛函數(shù)時(shí)由于DeriveA重寫(xiě)了display函數(shù),所以調(diào)用DeriveA的display函數(shù),exec內(nèi)部調(diào)用say函數(shù)時(shí)由于say是普通函數(shù),所以此時(shí)調(diào)用的是BaseTest的say函數(shù)。
8 c->exec(); 因?yàn)閏為BaseTest類(lèi)型,所以調(diào)用的就是BaseTest的exec,內(nèi)部執(zhí)行的也是BaseTest的display和say。
9 b->exec2(); 因?yàn)閎是一個(gè)子類(lèi)BaseTest的指針,所以調(diào)用BaseTest的exec2函數(shù),exec2內(nèi)部調(diào)用display時(shí)觸發(fā)多態(tài)機(jī)制調(diào)用DeriveA的display,調(diào)用say時(shí)因?yàn)閟ay是普通函數(shù),所以調(diào)用BaseTest的say函數(shù)。
10 a.exec2(); 因?yàn)閍是DeriveA類(lèi)對(duì)象,且DeriveA實(shí)現(xiàn)了exec2,所以a調(diào)用DeriveA的exec2,這樣exec2內(nèi)部調(diào)用的都是DeriveA的say和display
11 c->exec2(); c為BaseTest類(lèi)對(duì)象,所以調(diào)用BaseTest類(lèi)的exec2以及display和say函數(shù)。
總結(jié)
考察一個(gè)函數(shù)是被子類(lèi)還是基類(lèi)調(diào)用時(shí)應(yīng)該分以下幾種情況
1 該函數(shù)是虛函數(shù)并且被子類(lèi)重寫(xiě),如果是基類(lèi)指針指向子類(lèi)對(duì)象,調(diào)用該函數(shù)則引發(fā)多態(tài)機(jī)制,調(diào)用子類(lèi)的虛函數(shù)
2 如果該函數(shù)時(shí)虛函數(shù)并且沒(méi)有被重寫(xiě),那么無(wú)論調(diào)用的對(duì)象是基類(lèi)指針還是子類(lèi)對(duì)象,還是基類(lèi)對(duì)象,
還是子類(lèi)指針都是調(diào)用基類(lèi)的這個(gè)虛函數(shù)
3 如果該函數(shù)不是虛函數(shù),如果該函數(shù)被子類(lèi)覆蓋(子類(lèi)重新定義了同名函數(shù)),那么調(diào)用規(guī)則就是子類(lèi)調(diào)用子類(lèi)的該函數(shù),
基類(lèi)調(diào)用該基類(lèi)的函數(shù)。
4 如果該函數(shù)不是虛函數(shù),并且子類(lèi)沒(méi)有定義同名函數(shù)(沒(méi)有覆蓋基類(lèi)同名函數(shù)),那么無(wú)論是子類(lèi)還是基類(lèi)的指針或者對(duì)象,
統(tǒng)一調(diào)用的是基類(lèi)的函數(shù)。
5 如果第4點(diǎn)里基類(lèi)的函數(shù)(沒(méi)有被子類(lèi)覆蓋),但是內(nèi)部調(diào)用了基類(lèi)的虛函數(shù),并且該虛函數(shù)被子類(lèi)重寫(xiě),這時(shí)內(nèi)部這個(gè)虛函數(shù)調(diào)用規(guī)則
就要看調(diào)用對(duì)象的實(shí)際類(lèi)型,符合1的調(diào)用標(biāo)準(zhǔn),多態(tài)就走子類(lèi),不是多態(tài)就走基類(lèi)(此時(shí)符合2標(biāo)準(zhǔn))
6 如果第3點(diǎn)里基類(lèi)的函數(shù)(被子類(lèi)覆蓋),但是內(nèi)部調(diào)用了基類(lèi)的虛函數(shù),并且該虛函數(shù)被子類(lèi)重寫(xiě),這時(shí)內(nèi)部這個(gè)虛函數(shù)調(diào)用規(guī)則
就要看調(diào)用對(duì)象的實(shí)際類(lèi)型,符合1的調(diào)用標(biāo)準(zhǔn),多態(tài)就走子類(lèi),不是多態(tài)就走基類(lèi)(此時(shí)符合2標(biāo)準(zhǔn))
資源鏈接
本文模擬實(shí)現(xiàn)了vector的功能。
到此這篇關(guān)于C++深入探究重載重寫(xiě)覆蓋的區(qū)別的文章就介紹到這了,更多相關(guān)C++重載重寫(xiě)覆蓋內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)不掛科指南之棧&隊(duì)列&數(shù)組詳解
自考重點(diǎn)、期末考試必過(guò)指南,這篇文章讓你理解什么是棧、什么是隊(duì)列、什么是數(shù)組。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-09-09
C語(yǔ)言 指針變量作為函數(shù)參數(shù)詳解
本文主要介紹C語(yǔ)言 指針變量作為函數(shù)參數(shù),這里整理了相關(guān)資料和示例代碼,以便大家學(xué)習(xí)參考理解知識(shí)點(diǎn),有需要的小伙伴可以參考下2016-08-08
C語(yǔ)言動(dòng)態(tài)開(kāi)辟內(nèi)存詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言動(dòng)態(tài)開(kāi)辟內(nèi)存,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02
C語(yǔ)言雙指針?biāo)惴ㄅ笥堰^(guò)情人節(jié)我過(guò)算法
這篇文章主要為大家介紹了C語(yǔ)言中雙指針?biāo)惴ǖ氖纠斀?,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-02-02
C語(yǔ)言創(chuàng)建動(dòng)態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下)
本篇文章主要介紹了C語(yǔ)言創(chuàng)建動(dòng)態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-11-11
C++集體數(shù)據(jù)交換實(shí)現(xiàn)示例講解
這篇文章主要介紹了C++集體數(shù)據(jù)交換實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-11-11

