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