<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們先實現一個基礎類別
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類中我們實現了一個虛擬函式display和 func。
BaseTest類內部過載了f1函數,實現了兩個版本,一個引數為string一個引數為int。
同一個類中的多個同名函數叫做過載。
實現了普通函數say,exec以及exec2函數。exec和exec2函數內部呼叫了display和say函數。
子類DeriveA繼承了基礎類別
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(); } };
子類DeriveA 子類重新實現了display和func函數,子類重新實現父類別的虛擬函式,叫做重寫。
同樣子類重新實現了f1和say函數,由於父類別有f1和say,所以子類重新實現覆蓋了父類別的函數,
這種普通函數被子類重寫導致父類別的函數被隱藏了,叫做覆蓋。
接下來我們通過函數呼叫,看一下覆蓋,過載和重寫的區別
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(); }
程式碼裡我們生成了一個DeriveA的範例a, 並將該範例返回給基礎類別BaseTest的指標b,所以:
1 b->func();會根據多型的效果呼叫子類DeriveA的func函數
2 a.func() 因為a是一個物件,所以呼叫子類DeriveA的func函數
3 b->f1(“abc”) 呼叫基礎類別BaseTest的f1,因為f1是一個普通函數
4 a.f1(3, 5) 呼叫DeriveA的f1,因為a是一個普通物件。
5 當我們想在子類裡呼叫基礎類別的f1函數,可以通過基礎類別作用域加函數名的方式,比如例子中的
a.use_base_f1就在函數內部通過BaseTest::f1呼叫了基礎類別函數f1
6 b->exec,首先b是一個指標且exec為普通函數只在基礎類別實現了,所以呼叫基礎類別的exec,
但是exec內部呼叫了虛擬函式display,此時觸發多型機制呼叫DeriveA的display函數,因為b是一個指向子類DeriveA物件的基礎類別BaseTest指標,exec內部呼叫了普通函數display,因為display不是虛擬函式,所以呼叫BaseTest的display函數
7 a.exec(); a是一個DeriveA物件,DeriveA自己沒有實現exec函數,所以呼叫基礎類別BaseTest的exec函數,exec內部呼叫display虛擬函式時由於DeriveA重寫了display函數,所以呼叫DeriveA的display函數,exec內部呼叫say函數時由於say是普通函數,所以此時呼叫的是BaseTest的say函數。
8 c->exec(); 因為c為BaseTest型別,所以呼叫的就是BaseTest的exec,內部執行的也是BaseTest的display和say。
9 b->exec2(); 因為b是一個子類BaseTest的指標,所以呼叫BaseTest的exec2函數,exec2內部呼叫display時觸發多型機制呼叫DeriveA的display,呼叫say時因為say是普通函數,所以呼叫BaseTest的say函數。
10 a.exec2(); 因為a是DeriveA類物件,且DeriveA實現了exec2,所以a呼叫DeriveA的exec2,這樣exec2內部呼叫的都是DeriveA的say和display
11 c->exec2(); c為BaseTest類物件,所以呼叫BaseTest類的exec2以及display和say函數。
考察一個函數是被子類還是基礎類別呼叫時應該分以下幾種情況
1 該函數是虛擬函式並且被子類重寫,如果是基礎類別指標指向子類物件,呼叫該函數則引發多型機制,呼叫子類的虛擬函式
2 如果該函數時虛擬函式並且沒有被重寫,那麼無論呼叫的物件是基礎類別指標還是子類物件,還是基礎類別物件,
還是子類指標都是呼叫基礎類別的這個虛擬函式
3 如果該函數不是虛擬函式,如果該函數被子類覆蓋(子類重新定義了同名函數),那麼呼叫規則就是子類呼叫子類的該函數,
基礎類別呼叫該基礎類別的函數。
4 如果該函數不是虛擬函式,並且子類沒有定義同名函數(沒有覆蓋基礎類別同名函數),那麼無論是子類還是基礎類別的指標或者物件,
統一呼叫的是基礎類別的函數。
5 如果第4點裡基礎類別的函數(沒有被子類覆蓋),但是內部呼叫了基礎類別的虛擬函式,並且該虛擬函式被子類重寫,這時內部這個虛擬函式呼叫規則
就要看呼叫物件的實際型別,符合1的呼叫標準,多型就走子類,不是多型就走基礎類別(此時符合2標準)
6 如果第3點裡基礎類別的函數(被子類覆蓋),但是內部呼叫了基礎類別的虛擬函式,並且該虛擬函式被子類重寫,這時內部這個虛擬函式呼叫規則
就要看呼叫物件的實際型別,符合1的呼叫標準,多型就走子類,不是多型就走基礎類別(此時符合2標準)
本文模擬實現了vector的功能。
到此這篇關於C++深入探究過載重寫覆蓋的區別的文章就介紹到這了,更多相關C++過載重寫覆蓋內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45