記得幾個月前看過C++虛函數的問題,當時其實就看懂了,最近筆試中遇到了虛函數竟然不太確定,所以還是理解的不深刻,所以想通過這篇文章來鞏固下。
裝逼一刻:
最近,本人思想發生了巨大的轉變,在大學的時候由於讀書少,經常寫一些玩具程序而沾沾自喜,總之一句話,那時寫程序純粹是為了寫程序而寫程序。然而,作為大部分的學習者來說,往往忽略了學習開發語言的本質。即C++語言的設計思想也是以服務生產生活為主的,總結成一句話就是C++是實用的。我們在學習這門語言的一些特性的時候,上來就開始直接去記憶或者揣摩這些特性的本身往往不是一個很好的學習方法。
當你弄明白了這個特性是為了解決什么問題而設計的時候,在現實中有那些應用的時候,再去結合理解這些特性就會很容易理解的更深刻,更難忘。
同時,寫程序也一樣,作為一個以前上來就開始寫程序的人深深覺得以前的自己很愚蠢。哪怕你去寫一個很簡單的接口函數,都要去盡量的想,這個程序的參數可能是有那些人通過那些操作來傳遞的,他們可能出現的誤操作是那些?如果出現了誤操作該怎么去處理?當想清楚了這一切再去寫函數。(想的多的人,往往比上來蠻干的人,要牛x的多。)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
so,既然裝了那么多逼,那么為什么要設計虛函數這個概念呢!
談到這里,不得不談下多態,有人經常會問什么是多態?其實,多態簡單的說就是不同的對象受到相同的刺激而產生的不同反應。最直接明了的例子就是在windows平台下,你雙擊不同類型的文件,會調用不同的關聯軟件去打開一樣。比如,點擊word類型文件,系統會調用word來打開,點擊一個.mp4文件,快播就默默的蹦出來了。所以,這就是多態,一個相同的動作,遇到不同的對象產生不同的反應,就是這么一致和高效。
可能有人會說了我擦,這特么不太正常了嗎!點擊不同的文件,出現不同的反應在人類來看這也許就是天經地義的事情,並沒有什么呀!可是作為一門語言想要達到這樣的效果,還是需要一番深思熟慮的考慮以及巧妙的設計,當然這些人都是頂級的計算機專家了。他們為了解決這些我們人類邏輯看來天經地義的事情而設計了虛函數。
從某種程度上來講,虛函數是為實現多態而存在的。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
show code:
接下來就到了我們最喜歡的show code環節:為了方便理解,仍然舉雙擊文件的例子。
我們假設這里有三個類,分別是 基類 - CFile 派生類 - CMovie 派生類 - CMusic 。三個派生類分別代表,電影文件 音樂文件 。
假如這些文件都有一個接受雙擊后的函數反應,定義為Clicked。
因此有了下面簡單的代碼:
1 /********************************************************************** 2 programe: butter know virtual function 3 auther: heat nan 4 data: 2015.8.19 5 mail: 964465194@qq.com 6 ************************************************************************/ 7 8 #include<iostream> 9 using namespace std; 10 class CFile 11 { 12 public: 13 CFile() 14 { 15 } 16 virtual void Clicked() 17 { 18 cout<<"I am doing nothing!"<<endl; 19 } 20 }; 21 class CMovie:public CFile 22 { 23 public: 24 CMovie() 25 { 26 cout<<"My name is wujiandao!"<<endl; 27 } 28 void Clicked() 29 { 30 cout<<"Video type,KuaiBo will running!"<<endl; 31 } 32 }; 33 class CMusic:public CFile 34 { 35 public: 36 CMusic() 37 { 38 cout<<"My name is the fox!"<<endl; 39 } 40 void Clicked() 41 { 42 cout<<"Music type,Kugou will running!"<<endl; 43 } 44 }; 45 int main() 46 { 47 CFile A; 48 CMovie W; 49 CMusic F; 50 51 CFile *ptr=&A; 52 53 ptr=&W; 54 ptr->Clicked(); 55 56 ptr=&F; 57 ptr->Clicked(); 58 return 0; 59 }
有了上面,如此簡單粗暴的例子,以及一個很直觀的多態例子,相信對為什么要虛函數,以及引入虛函數做什么就很清楚了。
其實上面這個簡單的例子我覺得就可以這樣理解,ptr這個指針呢,就可以理解為雙擊操作,當然實時情況並不是這樣,這里只是簡化理解,當這個指針操作不同類型的文件時產生不同的反應。那么,不用Clicked函數不聲明為虛函數可以嗎?答案是否定的。不信可以試試。
一定要明白一件事情:虛函數不是為什么有這樣的功能,而是人們為了實現某種特定的功能而去設計的虛函數的一些特性和功能。
————————————————————————————————————————————————————————————————————————————
PS:虛函數的一些細節問題:
1 注意到繼承類中的Clicled()函數中並沒有添加關鍵字virtual,這是因為虛函數是一種強繼承類型的函數,只要在繼承類中函數名以及參數的形式和基類的相同,那它就會被認為是一個虛函數。因此,基類中的virtual關鍵字是不能省的。
2 虛函數完成多態的展現,需要指針的配合。(引用也可以,這個設計到虛函數的實現,本文直說理解,暫不討論)
3 不能將構造函數定義為虛函數。(具體查看http://blog.csdn.net/jiadebin890724/article/details/7951520)
4 虛函數必須是類的成員函數,但不能是靜態成員函數。(具體討論 http://bbs.csdn.net/topics/360075548)
暫且先這樣吧!