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

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是verbose和/或模板化的时候。

事实上,super是在Java和c#中实现的(在c#中,它被称为“base”,除非我错了)。但是c++缺少这个关键字。

我的问题是:

这种typedef的使用在你工作的代码中是超级常见/罕见/从未见过吗? 这种typedef的使用是超级Ok(也就是说,你看到强烈或不那么强烈的理由不使用它)? “super”应该是一个好东西吗?它应该在c++中标准化吗?或者通过类型定义来使用已经足够了吗?

编辑:Roddy提到的事实类型定义应该是私有的。这意味着任何派生类在不重新声明它的情况下都不能使用它。但我猜它也会阻止super::super链接(但谁会为它哭泣呢?)

编辑2:现在,在大量使用“super”几个月后,我完全同意罗迪的观点:“super”应该是私人的。


当前回答

我只是找到了一个替代方案。我有一个大问题与类型定义方法今天咬我:

类型定义需要类名的精确副本。如果有人改变了类名,但没有改变类型定义,那么你就会遇到问题。

所以我用一个非常简单的模板想出了一个更好的解决方案。

template <class C>
struct MakeAlias : C
{ 
    typedef C BaseAlias;
};

所以现在,不是

class Derived : public Base
{
private:
    typedef Base Super;
};

你有

class Derived : public MakeAlias<Base>
{
    // Can refer to Base as BaseAlias here
};

在本例中,BaseAlias不是私有的,我已经尝试通过选择一个应该提醒其他开发人员的类型名称来防止粗心使用。

其他回答

Super(或inherited)是非常好的东西,因为如果你需要在Base和Derived之间插入另一个继承层,你只需要改变两件事:“class Base: foo”和2。的类型定义

如果我没记错的话,c++标准委员会正在考虑为这个添加一个关键字…直到迈克尔·蒂曼(Michael Tiemann)指出这种类型的技巧是有效的。

至于多重继承,因为它在程序员的控制下,你可以做任何你想做的:也许是super1和super2,或者其他什么。

我不知道这种情况是否罕见,但我肯定也做过同样的事情。

正如前面所指出的,当一个类使用多重继承时,这部分语言本身的困难就出现了。

为什么c++不支持“super”关键字的简单答案是。

DDD(死亡之钻)问题。

在多重继承中。编译器会混淆哪个是超类。

那么哪个超类是D的超类呢??“Both”不能是解决方案,因为“super”关键字是指针。

我总是用“inherited”而不是super。(可能是由于Delphi背景),我总是使它私有,以避免当“继承”被错误地从一个类中省略,但一个子类试图使用它时的问题。

class MyClass : public MyBase
{
private:  // Prevents erroneous use by other classes.
  typedef MyBase inherited;
...

我创建新类的标准“代码模板”包括typedef,所以我很少有机会不小心忽略它。

我不认为链式的“super::super”建议是一个好主意——如果您这样做,您可能会非常困难地绑定到一个特定的层次结构,并且更改它可能会严重破坏东西。

Bjarne Stroustrup在《c++的设计与发展》一书中提到,在c++第一次标准化时,ISO c++标准委员会就考虑将super作为关键字。

Dag Bruck提出了这个扩展,称基类为“继承的”。该提案提到了多重继承问题,并标记了不明确的用途。甚至斯特劳斯特鲁普也被说服了。

经过讨论,Dag Bruck(是的,就是提出该提案的同一个人)写道,该提案是可实现的,技术上是合理的,并且没有重大缺陷,并且处理了多重继承。另一方面,这并没有带来足够的回报,委员会应该处理一个更棘手的问题。

Michael Tiemann来晚了,然后用这篇文章中提到的同样的技巧展示了一个typedef'ed super可以很好地工作。

所以,不,这可能永远不会标准化。

如果你没有副本,《Design and Evolution》的封面价格也物有所值。用过的拷贝花10美元就能买到。