面試的時候被問到虛函式,這兩天就研究下虛函式,真是基礎啊!!
下面先來點簡單的
簡單地說,那些被virtual關鍵字修飾的
成員函式,就是虛函式。虛函式的作用,用專業術語來解釋就是實現
多型性(polymorphism),多型性是將介面與實現進行分離;用形象的語言來解釋就是實現以共同的方法,但因個體差異,而採用不同的策略。下面來看一段簡單的**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include
using
namespace
std;
class
a
};
class
b :
public
a
};
int
main()
分別是「thisisa」、「thisisb」。通過class a和class b的print()這個介面,可以看出這兩個class因個體的差異而採用了不同的策略,但這是否真正做到了
多型性呢?no,多型還有個關鍵之處就是一切用指向
基類的指標或引用來操作物件。那現在就把main()處的**改一改。
1
2
3
4
5
6
7
8
9
10
11
int
main()
執行一下看看結果,喲呵,驀然回首,結果卻是兩個this is a。問題來了,p2明明指向的是class b的物件但卻是呼叫的class a的print()函式,這不是我們所期望的結果,那麼解決這個問題就需要用到虛函式
1
2
3
4
5
6
7
8
9
10
11
class
a
;
class
b :
public
a
;
毫無疑問,class a的
成員函式print()已經成了虛函式,那麼class b的print()成了虛函式了嗎?回答是yes,我們只需在把基
類的成員函式設為virtual,其
派生類的相應的函式也會自動變為虛函式。所以,class b的print()也成了虛函式。那麼對於在
派生類的相應函式前是否需要用virtual關鍵字修飾,那就是你自己的問題了。
現在重新執行main2的**,這樣輸出的結果就是this is a和this is b了。
現在來消化一下,我作個簡單的總結,指向
基類的指標在操作它的
多型類物件時,會根據不同的類物件,呼叫其相應的函式,這個函式就是虛函式。
到此我們肯定會好奇為什麼a *p2 = &b;之後p2呼叫的卻是a的函式,為什麼??是因為指向基類的指標指向派生類物件時 呼叫函式呼叫的是基類的函式。
這裡我想再對隱藏和覆蓋再討論一下,見下:
在看《高質量c/c++》中看到了函式的隱藏和覆蓋是這麼說的:
覆蓋的是指子類函式覆蓋基類函式
在不同的類內(分別位於子類和父類)。
同名同參。
基類的函式名前必須有virtual關鍵字。
隱藏指派生類的函式隱藏了基類的同名函式
如果派生類函式與基類函式同名,但引數不同,無論基類函式前是否有virtual修飾,基類函式被隱.
如果派生類函式與基類函式同名,引數也相同,但是基類函式前無virtual修飾,基類函式被隱藏。
上面說的這些也叫做動態繫結。。
動態繫結是指在執行期間(非編譯期)判斷所引用物件的實際型別,根據其實際的型別呼叫其相應的方法。
程式執行過程中,把函式(或過程)呼叫與響應呼叫所需要的**相結合的過程稱為動態繫結。
而靜態繫結是指在
程式編譯
過程中,把函式(方法或者過程)呼叫與響應呼叫所需的**結合的過程稱之為靜態繫結。
虛函式複習
虛函式聯絡到多型,多型聯絡到繼承。所以本文中都是在繼承層次上做文章。沒了繼承,什麼都沒得談。下面是對c 的虛函式這玩意兒的理解。一,什麼是虛函式 如果不知道虛函式為何物,但有急切的想知道,那你就應該從這裡開始 簡單地說,那些被virtual關鍵字修飾的成員函式,就是虛函式。虛函式的作用,用專業術語來...
C C 複習之 虛函式
物件導向程式設計的基本特徵 抽象 封裝 繼承 多型 c 中,多型分為編譯時的多型性和執行時的多型性。編譯時的多型是通過函式過載實現的,執行時的多型是通過虛函式實現的。虛函式是過載的另一種形式。這是一種動態的過載方式,它提供了一種更為靈活的執行時的多型機制。虛函式允許函式呼叫於函式體之間的聯絡在程式執...
C 知識複習 多型 虛函式
兩個半月沒更部落格,人變得更菜了,開始挖個複習大坑。1.c 的三大特性 封裝 繼承 多型。2.多型 用一句話來概括,多型就是同一函式 方法 作用於不同的物件時,可以有不同的解釋,產生不同的執行結果。在面向程式設計中使用多型,能大大提高程式的可擴充性 include using namespace s...