深入剖析C++繼承,多態以及隱藏(二)。(純虛函數以及重寫與隱藏)

一,純虛函數;

1,在C++中引入了純虛函數來定義一個公共的接口函數,定義一個接口。

1)語法: virtual 函數聲明 =0;

2),純虛函數使得基類成爲抽象類,抽象類也就是隻能被繼承用以提供一個接口,而不能被實例化的類。

3),如果基類中有一個類被聲明爲純虛函數,那麼V-Table就不完整;

對於純虛函數,V-Table只會爲其留出空間但是上面沒有其地址。這也就決定了抽象類無法實例化!

4),但是對於在C++中而言純虛函數可以被定義,這種設計是爲了讓一些在以後的方法中重複的代碼能夠被提取出來。
同時也更好的支持從虛函數到純虛函數的改變。

2,純虛函數的設計理念---OOP設計。關係;

純虛函數對應的一個純虛類,事實上是在設計的過程中,當某些事物並不是一種實際的物體而是人們意識中的一種抽象的形態;
例如,你想設計一個編輯器,他可以進行繪製各種形狀。圓形,方形等等。但是這個當中顯然形狀就是一種抽象的東西!

C++中關於這方面的設計跟JAVA中的區別可以參考下面:

http://www.xxlinux.com/linux/article/development/soft/20060729/3177.html

二,重寫VS隱藏;

在C++中嚴格的規定對於虛函數以及相應的動態綁定的語法要求:

首先,想實現重寫的話,基類中必須聲明是virtual;
其次,派生類中重寫時候,其參數列表,返回類型,函數名都必須相同!(對於參數類型有特殊例子。)

否則的話,編譯器就無法支持向上類型轉化中的動態綁定!如果函數名相同且不滿足重寫的話,那麼就是被隱藏了!

特殊情況:

如果說在派生類中重寫虛函數的時候返回的類型是基類當中返回類型的派生類的時候,那麼此時編譯器是允許的!

而且!這個過程中也應該儘量的按照確定的類型去返回,否則如果單純的遵守語法規定而按照基類中的返回類型的話,反而得不到正確的類型,還需要向下轉化!

實例:見 C++編程思想第一卷15章 P373頁!

三,虛函數與構造函數;虛函數與析構函數。

1,構造函數;

1)對於構造函數而言,他的任務就是保證順利的創建這個類。因此在繼承層次中,順利的調用基類函數的構造函數以及順利的初始化組合對象是構造函數進入其函數體必須做的一件事;

同時如果類中存在虛函數,從上一節中我們已經瞭解到了,虛函數VPTR是由構造函數初始化的;

顯然在這個過程是發生在構造函數體前,因此他的V-Table就是當地的版本;

2)構造函數不能爲虛函數,也不能支持虛機制!

如果支持的話,那麼通過動態綁定在構造函數中就訪問子類中的函數版本,但是子類都還未被創建。因此顯然是不行的!

2,析構函數;

1)如果類中有虛函數的話那麼,應該將析構函數顯示的表示成虛函數。因爲如果通過動態綁定的過程,由基類指針訪問派生類的函數,而在delete這個指針的時候顯然只能調用基類的析構函數。如果不是虛函數的話那麼就無法釋放剛纔這個過程中new出來的派生類的對象。將會導致memory leak!

2)析構函數中同樣不能支持虛機制。那樣有可能導致去調用一個已經被delete的對象.


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/slowboy1990/archive/2008/11/20/3341017.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章