2014-12-29 157 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

相关问题