2012-03-18 130 views

回答

6

當你有聲明爲virtual一個基類方法,爲了覆蓋它,你需要提供一個功能,在派生類(共變的返回類型被允許雖然)完全相同的簽名。

如果你的函數名是相同的,但在派生類中籤名從一個基類變化比它不是overidding了,這是function Hiding,派生類的方法隱藏基類的方法。

函數重載永遠不會跨類,您可以重載同一類或自由函數中的方法,但不能跨類。當你試圖通過類來完成時,你最終得到的是函數隱藏。

要將基類方法引入到派生類的範圍中,您需要向Derived類添加
其他using functionName

編輯:
至於何時在重載使用virtual的Q,答案是:
如果你想你的類的功能,將其覆蓋以運行時多態性,你應該將其標記爲virtual,而不是如果你不打算的話。

讀取良好:
When to mark a function in C++ as a virtual?

+0

要重載派生類中的基類成員函數,只需要一個'using'聲明。 – Potatoswatter 2012-03-18 07:18:20

+0

@Patatoswatter:是的,除了提供方法之外,您還需要這樣做,因此從這個意義上說,它不僅僅提供重載版本。 – 2012-03-18 07:19:22

+0

我也在試圖制定一個答案,但我無法解釋在基礎虛擬中做出功能與否之間的差異。您可以在派生類中使用相同的方式重載兩者(使用不同的簽名)。我認爲這是OP問題的一部分。 – 2012-03-18 07:22:44

3

重載是從(正交)虛擬首要完全分開的。

重寫時,一個函數被替換爲另一個相同的簽名。然後有一些規則選擇「最重要的」功能,這對於虛擬功能來說意味着在最派生的類中定義的功能。作爲虛擬函數的特例,簽名的返回類型可能略有不同(協方差)。

在重載中,具有不同參數類型的函數簽名同時充當您進行函數調用時要選擇的候選項。有一套非常複雜的規則來挑選合適的規則,這在95%的時間內運行良好,當它不合作時會讓你頭疼。

由於重載使用不同的簽名和重寫使用相同簽名的作品,因此它們並不會真正互相干擾。

您可以顯式地將基類的函數導入派生類,以擴展重載的函數名稱。這由派生類中的using base_class::overload_name;完成。

0

我相信你的意思是覆蓋非虛函數,而不是重載。當您在派生類中重寫非虛擬基類函數時,則在編譯時解析並綁定對該函數的調用。這意味着函數調用是根據調用函數的類型(或指針)來解析的。如果您在基類指針上調用該函數,則始終調用基類版本。如果您使用派生類指針,則始終調用派生版本;不管它指向的實際對象如何。

如果基類版本被標記爲虛擬的,那麼調用解析或綁定被延遲爲在運行時基於調用的對象的類型而不是基於正被用於指針的類型撥打電話。這意味着您可以使用基類指針指向基類和派生類對象,然後調用該函數。根據指針指向的對象類型,調用相應的函數版本。這意味着如果我的指針指向基類對象,那麼將調用基類版本。如果指針指向派生類型對象,則調用派生的版本。

+0

要說一個派生類** overiddes **的基類功能,關鍵字'虛擬'必須涉及否則,它不overidding。 – 2012-03-18 07:57:31

+0

不,它仍然是壓倒一切的。但是,如果您不使用虛擬,那麼基類版本會被派生類版本所取代。而且沒有辦法選擇你想要使用的版本。現在,如果您想讓所有重寫的版本仍然可用,那麼您應該將它們標記爲虛擬。 – Drona 2012-03-18 08:15:51

+0

對不起,打破它給你,但它不正確,如果沒有'虛擬'關鍵字,那麼它不overveding。 – 2012-03-18 08:19:22