2014-12-29 198 views
0

我目前正在使用C++模板搞亂CRTP模式。在用visual studio擺弄時,我發現了派生類可以調用函數的基類實現的幾種方式/方法。下面是我正在使用的代碼,還有3條註釋掉的行顯示瞭如何從派生類調用函數的基類實現。使用一種方法比另一種方法有好處嗎?有什麼區別嗎?什麼是最常用的方法?CRTP - 如何從派生類調用基類的實現方法?

template<typename T> 
struct ConsoleApplication 
{ 

    ConsoleApplication() 
    { 
     auto that = reinterpret_cast<T*>(this); 
     that->ShowApplicationStartupMsg(); 
    } 



    void ShowApplicationStartupMsg() 
    { 

    } 
}; 


struct PortMonitorConsoleApplication : ConsoleApplication <PortMonitorConsoleApplication> 
{ 
    void ShowApplicationStartupMsg() 
    { 
     // __super::ShowApplicationStartupMsg(); 
     // this->ShowApplicationStartupMsg(); 
     // ConsoleApplication::ShowApplicationStartupMsg(); 
    } 
}; 
+0

爲什麼在基類和派生歸入都需要'ShowApplicationStartupMsg()'?如果派生除了調用基礎之外什麼也不做,你應該在派生類中省略版本。 – willj

+1

這三個中只有一個是調用隱藏基方法的有效方法。 – hvd

+1

您的基類構造函數具有未定義的行爲。基礎正在初始化,但派生實例的成員和其成員都沒有被初始化。您正在調用尚未完全初始化的對象。你也不應該在這裏使用'reinterpret_cast',而應該使用'static_cast'。 –

回答

1

我見過的最好的方法是使用這樣的:

ConsoleApplication::ShowApplicationStartupMsg();

這是好的,因爲它是很清楚你想要做什麼,被稱爲什麼父類的方法from(特別有用的,如果你不是父類本身是派生類)。

0
ConsoleApplication <PortMonitorConsoleApplication>::ShowApplicationStartupMsg(); 

使用你的基類的全名。

需要注意的是這個 - > ShowApplicationStartupMsg()不叫你的基地,它再次調用自己的函數。

__super不規範(不應該成爲一個,因爲它是不明確的多個基地)。

使用ConsoleApplication ::不完全是標準的(雖然我覺得GCC接受它),你不會從ConsoleApplication本身,只是其中的具體實例繼承。

+0

「使用ConsoleApplication ::不完全標準」 - 實際上是這樣。如果語言按照您的想法進行定義,那麼語言仍然會很有意義,但它並不是以這種方式定義的。 :)如果你喜歡,請查找「注入類名」。 – hvd

+0

會這麼做 - 因爲我知道我們有一些工作中的錯誤報告,因爲它沒有在某些角落編譯器上編譯。 – dascandy

相關問題