在C ++中使用“ super”

我的编码风格包括以下成语:


class Derived : public Base

{

   public :

      typedef Base super; // note that it could be hidden in

                          // protected/private section, instead


      // Etc.

} ;

这使我可以将“ super”用作Base的别名,例如,在构造函数中:


Derived(int i, int j)

   : super(i), J(j)

{

}

甚至当从基类的重写版本中调用该方法时:


void Derived::foo()

{

   super::foo() ;


   // ... And then, do something else

}

它甚至可以被链接(尽管我仍然需要找到它的用途):


class DerivedDerived : public Derived

{

   public :

      typedef Derived super; // note that it could be hidden in

                             // protected/private section, instead


      // Etc.

} ;


void DerivedDerived::bar()

{

   super::bar() ; // will call Derived::bar

   super::super::bar ; // will call Base::bar


   // ... And then, do something else

}

无论如何,我发现使用“ typedef super”非常有用,例如,当Base是冗长的和/或模板化时。


事实是,super是在Java和C#中实现的,除非我错了,否则在C#中将其称为“基础”。但是C ++缺少此关键字。


所以,我的问题是:


您使用的代码中是否经常使用typedef super common / rare / never?

使用typedef super是可以的吗(即您是否出于强烈的理由不使用它)?

“ super”应该是一件好事吗,应该在C ++中进行某种标准化,还是通过typedef进行使用已经足够了?

编辑: Roddy提到了typedef应该是私有的事实。这将意味着任何派生类都必须重新声明它才能使用它。但是我想它也会阻止super :: super链接(但是谁会为此哭泣?)。


编辑2:现在,在大规模使用“超级”几个月后,我完全同意罗迪的观点:“超级”应该是私有的。我会两次投票赞成他的回答,但我想我不能。


繁花如伊
浏览 598回答 3
3回答

肥皂起泡泡

我一直使用“继承”而不是超级。(可能是由于Delphi的背景),我总是将其设置为private,以避免在类中错误地省略“继承”但子类尝试使用它时的问题。class MyClass : public MyBase{private:  // Prevents erroneous use by other classes.  typedef MyBase inherited;...用于创建新类的标准“代码模板”包括typedef,因此我几乎没有机会无意忽略它。我认为链式的“ super :: super”建议不是一个好主意-如果这样做,您可能很难与特定的层次结构绑定在一起,并且更改它可能会严重破坏某些东西。

青春有我

这样做的一个问题是,如果您忘记(重新)定义派生类的super,那么对super :: something的任何调用都会编译良好,但可能不会调用所需的函数。例如:class Base{public:  virtual void foo() { ... }};class Derived: public Base{public:    typedef Base super;    virtual void foo()    {        super::foo();   // call superclass implementation        // do other stuff        ...    }};class DerivedAgain: public Derived{public:    virtual void foo()    {        // Call superclass function        super::foo();    // oops, calls Base::foo() rather than Derived::foo()        ...    }};(如Martin York在对此答案的评论中所指出的,可以通过将typedef设置为私有而不是公共或受保护来消除此问题。)
打开App,查看更多内容
随时随地看视频慕课网APP