2013-08-27 37 views
1

我只是學會了讓我驚訝的是,以下是合法的C++具有函數體的純虛成員函數的要點是什麼?

struct A { 
    void foo(int) const = 0; // pure virtual 
    // ... 
}; 
void A::foo(int) const { /* ... */ } 

什麼是合理的用例呢?即A::foo何時會被調用,爲什麼這是正確的/最好的實現? C++ 03和C++ 11之間有什麼區別嗎?


好的,有一個以前的問題(我沒有找到)具有相同的意圖。不過那是C++ 11之前的版本。所以我最後的問題仍然有效。

+0

感謝,指出前面的問題描述。我的搜索沒有提到它。但是,這個問題是C++ 11之前的版本。所以我的問題的最後一部分仍然沒有答案。 – Walter

+0

只是爲了確認「void foo(int)const = 0;」這是否是聲明純虛函數的有效方法,即使沒有虛擬關鍵字? – dearvivekkumar

回答

4

什麼是明智的用例呢?

如果該函數有一個合理的默認實現或部分實現與基類有關的任何東西,但仍想強制派生類重寫它,那麼這是一個放置它的好地方。

另外,正如評論中指出的那樣,您可能希望強制一個沒有純虛函數的類是抽象的。你可以通過使析構函數純粹爲虛擬來做到這一點。但是析構函數必須有一個主體,不管它是否是純虛擬的。

什麼時候會A::foo被稱爲?

它只能被稱爲非虛擬的;例如:

struct B : A { 
    void f(int i) const { 
     A::foo(i); // non-virtual call 
     // Do the B-specific stuff 
    } 
}; 

爲什麼這是正確的/最好的實現?

除了未實現的純虛函數之外,另一種方法是爲部分/默認實現發明一個新名稱。

C++ 03和C++ 11之間有什麼區別嗎?

+1

+1,我還會補充一點,常見用例是一個純粹的虛擬析構函數,它有時用於強制創建派生類型,但它必須具有一個定義,因爲派生類型必須調用基本析構函數。 –

+0

@DavidRodríguez-dribeas:好點,我已經添加了一個關於這個的筆記。 –

3

規範的用例是通過提供一個純虛析構函數來標記一個類爲抽象類 - 它必須有一個實現。

自從C++ 98之前就已經是規則。

+0

嗯 - 「實現」==「帶身體」,不是嗎? – SteveLove

+1

@MikeSeymour:他不是在談論任何*函數,而是必須定義**析構函數。 –

+0

對不起,我誤解了答案。 +1。 –

1

當然是合法的。 純虛函數的意思是它聲明的那個類的實例不能被實例化,而不是它沒有實現。例如,它就像C#中的接口一樣。

它提供了什麼機會?
1.客戶端可以使用默認實現
2。與純虛析構函數類不再提高鏈接錯誤 (當你申請刪除對指針的基類:派生類的析構函數被調用,基類的那個析構函數之後被調用,如果你ommit實施 - 連接器將提出錯誤)。

參考文獻:需要在純虛方法的實現進行了詳細的書「有效的C++」,由斯科特·邁爾斯