2011-04-06 110 views
4

考慮一個場景,其中有兩個類,即Base和Derived。如果基類要調用派生類的函數,則可以通過創建虛擬函數並在派生類中定義該VF或使用回調來實現。我想知道兩者中應該選擇哪一個?兩者之間的選擇取決於哪些情況/條件?虛擬功能與回調

編輯: 問題澄清:

我指的是所述的情況是,有其接收消息的基類。這些不同的消息將由派生類以不同方式處理,所以一種方法是創建一個虛擬函數並讓派生類實現它,通過各種開關情況處理每條消息。

另一種方法是通過模板內部的函數指針(指向派生類的函數)實現回調(需要模板來處理派生類和函數名稱的對象)。模板和函數指針將駐留在基類中。

+1

我想你需要提供一個具體的例子來澄清你的問題,如果你仍然在尋找答案。我不明白你爲什麼需要'各種開關盒',例如選項一。通過程序設計通常有這樣的方法。在第二種選擇中,您不清楚模板的含義。你是在談論C++'templates'還是某種包含信息來識別函數指針的消息模板?更具體的東西,即使它是僞代碼也是有幫助的。 – forsvarir 2011-05-24 11:42:39

+0

@forsvarir感謝您的回覆,我會在幾天後跟進。 – 2011-05-24 11:51:15

+0

@forsvarir請原諒我不跟進這個話題。我***會在幾天內回到這個問題,還有其他一些問題。我完全記得它們,但是現在我的碟子上有太多菜。將很快跟進。 – 2012-04-05 07:15:17

回答

4

虛擬函數調用實際上是一個回調函數

調用者在對象的虛函數表中查找對應的條目並調用它。這就像一個回調的行爲,除了成員函數指針具有尷尬的語法。虛擬功能將工作卸載到編譯器,這使得它成爲一個非常優雅的解決方案。

虛擬函數是在繼承層次結構中進行通信的方式。

+0

感謝您的回覆,但我指的是通過模板實現的C++回調。其次,在特定情況下,兩者中的任何一個都是首選的原因肯定是有原因的? – 2011-04-06 10:23:04

+3

術語回調有點模糊。請舉一個例子,我們可以微調我們的反應(即將其添加到您的問題中) – 2011-04-06 10:24:39

+0

@kgiannakakis,@forsvarir:我已編輯該問題以獲得更多解釋,如果仍不清楚,請告訴我。 – 2011-04-13 06:36:22

4

我認爲這取決於您所談論的行爲是否屬於'Base'知道的關於兒童實施的層次。

如果使用回調解決方案,則回調方法(取決於簽名)不必在Base的子項中實現。例如,如果您想對可能在派生類中的「事件偵聽器」說'此事件已經發生',或者可能處於恰好對該事件感興趣的完全不相關的類中,這可能是合適的。

如果您使用虛擬功能解決方案,那麼您將更緊密地耦合Derived和Base類的實現。

一個有趣的閱讀,可能會回答你的問題的某種方式是:Callbacks in C++其中談論的Functors的用法。 Wikipedia也有一個使用模板回調進行排序的示例。您會注意到回調(這是一個比較函數)的實現不必位於執行排序的對象中。如果它是使用虛擬方法實現的,則情況並非如此。

+0

在我的情況下,基類不知道將要處理派生類的變化的派生類函數。我會看看你的鏈接,謝謝。 – 2011-04-13 06:38:33

1

我不認爲你描述的兩種情況是可比的。虛擬函數是一種多態工具,可幫助您擴展基類以提供附加功能。它們的關鍵特徵是在運行時決定哪個函數被調用。

回調是一個更一般的概念,它不僅適用於父子關係。所以,如果你想要做的事涉及擴展基類,我肯定會去虛擬功能。請確保瞭解虛擬功能的工作原理。