在 C++ 中使用“超级”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/180601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using "super" in C++
提问by paercebal
My style of coding includes the following idiom:
我的编码风格包括以下习语:
class Derived : public Base
{
public :
typedef Base super; // note that it could be hidden in
// protected/private section, instead
// Etc.
} ;
This enables me to use "super" as an alias to Base, for example, in constructors:
这使我能够使用“super”作为 Base 的别名,例如,在构造函数中:
Derived(int i, int j)
: super(i), J(j)
{
}
Or even when calling the method from the base class inside its overridden version:
甚至在其重写版本中从基类调用该方法时:
void Derived::foo()
{
super::foo() ;
// ... And then, do something else
}
It can even be chained (I have still to find the use for that, though):
它甚至可以被链接起来(不过,我仍然需要找到它的用途):
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
}
Anyway, I find the use of "typedef super" very useful, for example, when Base is either verbose and/or templated.
无论如何,我发现使用“typedef super”非常有用,例如,当 Base 是冗长的和/或模板化时。
The fact is that super is implemented in Java, as well as in C# (where it is called "base", unless I'm wrong). But C++ lacks this keyword.
事实是 super 是用 Java 和 C# 实现的(它被称为“base”,除非我错了)。但是 C++ 缺少这个关键字。
So, my questions:
所以,我的问题:
- is this use of typedef super common/rare/never seen in the code you work with?
- is this use of typedef super Ok (i.e. do you see strong or not so strong reasons to not use it)?
- should "super" be a good thing, should it be somewhat standardized in C++, or is this use through a typedef enough already?
- 在您使用的代码中,这种使用 typedef 是否超级常见/罕见/从未见过?
- 使用 typedef 是否超级好(即,您是否认为不使用它的强大或不那么强大的理由)?
- “超级”应该是一件好事,它应该在 C++ 中有些标准化,还是通过 typedef 已经足够了?
Edit:Roddy mentionned the fact the typedef should be private. This would mean any derived class would not be able to use it without redeclaring it. But I guess it would also prevent the super::super chaining (but who's gonna cry for that?).
编辑:Roddy 提到 typedef 应该是私有的。这意味着任何派生类都不能在不重新声明它的情况下使用它。但我想它也会阻止 super::super 链接(但谁会为此哭泣?)。
Edit 2:Now, some months after massively using "super", I wholeheartedly agree with Roddy's viewpoint: "super" should be private. I would upvote his answer twice, but I guess I can't.
编辑 2:现在,在大量使用“超级”几个月后,我完全同意 Roddy 的观点:“超级”应该是私密的。我会两次赞成他的回答,但我想我不能。
采纳答案by Max Lybbert
Bjarne Stroustrup mentions in Design and Evolution of C++that super
as a keyword was considered by the ISO C++ Standards committee the first time C++ was standardized.
Bjarne Stroustrup 在C++ 的设计和演进中提到,在super
C++ 首次标准化时,ISO C++ 标准委员会将其视为关键字。
Dag Bruck proposed this extension, calling the base class "inherited." The proposal mentioned the multiple inheritance issue, and would have flagged ambiguous uses. Even Stroustrup was convinced.
Dag Bruck 提出了这个扩展,称基类是“继承的”。该提案提到了多重继承问题,并标记了不明确的用途。甚至 Stroustrup 也被说服了。
After discussion, Dag Bruck (yes, the same person making the proposal) wrote that the proposal was implementable, technically sound, and free of major flaws, and handled multiple inheritance. On the other hand, there wasn't enough bang for the buck, and the committee should handle a thornier problem.
经过讨论,Dag Bruck(是的,提出提案的同一个人)写道,该提案是可实施的,技术上合理,没有重大缺陷,并处理了多重继承。另一方面,没有足够的回报,委员会应该处理更棘手的问题。
Michael Tiemann arrived late, and then showed that a typedef'ed super would work just fine, using the same technique that was asked about in this post.
Michael Tiemann 迟到了,然后展示了一个 typedef'ed super 可以很好地工作,使用与本文中提到的相同的技术。
So, no, this will probably never get standardized.
所以,不,这可能永远不会标准化。
If you don't have a copy, Design and Evolutionis well worth the cover price. Used copies can be had for about $10.
如果您没有副本,《设计与进化》绝对物超所值。用过的副本大约需要 10 美元。
回答by Roddy
I've always used "inherited" rather than super. (Probably due to a Delphi background), and I always make it private, to avoid the problem when the 'inherited' is erroneously omitted from a class but a subclass tries to use it.
我一直使用“继承”而不是超级。(可能是由于 Delphi 背景),并且我总是将其设为private,以避免在类中错误地省略“继承”但子类尝试使用它时出现问题。
class MyClass : public MyBase
{
private: // Prevents erroneous use by other classes.
typedef MyBase inherited;
...
My standard 'code template' for creating new classes includes the typedef, so I have little opportunity to accidentally omit it.
我用于创建新类的标准“代码模板”包括 typedef,所以我几乎没有机会意外地省略它。
I don't think the chained "super::super" suggestion is a good idea- If you're doing that, you're probably tied in very hard to a particular hierarchy, and changing it will likely break stuff badly.
我不认为链接的“super::super”建议是一个好主意——如果你这样做,你可能与特定的层次结构非常紧密地联系在一起,改变它可能会严重破坏东西。
回答by Kristopher Johnson
One problem with this is that if you forget to (re-)define super for derived classes, then any call to super::something will compile fine but will probably not call the desired function.
这样做的一个问题是,如果您忘记(重新)为派生类定义 super,那么对 super::something 的任何调用都可以正常编译,但可能不会调用所需的函数。
For example:
例如:
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()
...
}
};
(As pointed out by Martin York in the comments to this answer, this problem can be eliminated by making the typedef private rather than public or protected.)
(正如 Martin York 在对此答案的评论中所指出的,可以通过将 typedef 设为私有而不是公有或受保护来消除这个问题。)
回答by krujos
回答by Colin Jensen
Super (or inherited) is Very Good Thing because if you need to stick another inheritance layer in between Base and Derived, you only have to change two things: 1. the "class Base: foo" and 2. the typedef
Super(或继承)是非常好的事情,因为如果您需要在 Base 和 Derived 之间添加另一个继承层,您只需更改两件事:1.“class Base: foo”和 2. typedef
If I recall correctly, the C++ Standards committee was considering adding a keyword for this... until Michael Tiemann pointed out that this typedef trick works.
如果我没记错的话,C++ 标准委员会正在考虑为此添加一个关键字……直到 Michael Tiemann 指出这个 typedef 技巧有效。
As for multiple inheritance, since it's under programmer control you can do whatever you want: maybe super1 and super2, or whatever.
至于多重继承,因为它在程序员的控制之下,你可以做任何你想做的事情:也许是 super1 和 super2,或者其他什么。
回答by paperjam
I just found an alternate workaround. I have a big problem with the typedef approach which bit me today:
我刚刚找到了一个替代的解决方法。我对今天咬我的 typedef 方法有一个大问题:
- The typedef requires an exact copy of the class name. If someone changes the class name but doesn't change the typedef then you will run into problems.
- typedef 需要类名的精确副本。如果有人更改了类名但没有更改 typedef,那么您将遇到问题。
So I came up with a better solution using a very simple template.
所以我想出了一个使用非常简单的模板的更好的解决方案。
template <class C>
struct MakeAlias : C
{
typedef C BaseAlias;
};
So now, instead of
所以现在,而不是
class Derived : public Base
{
private:
typedef Base Super;
};
you have
你有
class Derived : public MakeAlias<Base>
{
// Can refer to Base as BaseAlias here
};
In this case, BaseAlias
is not private and I've tried to guard against careless usage by selecting an type name that should alert other developers.
在这种情况下,BaseAlias
不是私有的,我试图通过选择一个应该提醒其他开发人员的类型名称来防止粗心使用。
回答by Michael Burr
I don't recall seeing this before, but at first glance I like it. As Ferruccionotes, it doesn't work well in the face of MI, but MI is more the exception than the rule and there's nothing that says something needs to be usable everywhere to be useful.
我不记得以前看过这个,但乍一看我喜欢它。正如Ferruccio指出的那样,它在 MI 面前效果不佳,但 MI 更像是例外而不是规则,并且没有任何内容表明某些东西需要在任何地方都可用才能有用。
回答by Konrad Rudolph
I've seen this idiom employed in many codes and I'm pretty sure I've even seen it somewhere in Boost's libraries. However, as far as I remember the most common name is base
(or Base
) instead of super
.
我已经在许多代码中看到过这个习语,而且我很确定我什至在 Boost 的库中的某个地方看到过它。但是,据我所知,最常见的名称是base
(或Base
) 而不是super
。
This idiom is especially useful if working with template classes. As an example, consider the following class (from a real project):
如果使用模板类,这个习惯用法特别有用。例如,考虑以下类(来自真实项目):
template <typename TText, typename TSpec>
class Finder<Index<TText, PizzaChili<TSpec> >, PizzaChiliFinder>
: public Finder<Index<TText, PizzaChili<TSpec> >, Default>
{
typedef Finder<Index<TText, PizzaChili<TSpec> >, Default> TBase;
// …
}
Don't mind the funny names. The important point here is that the inheritance chain uses type arguments to achieve compile-time polymorphism. Unfortunately, the nesting level of these templates gets quite high. Therefore, abbreviations are crucial for readability and maintainability.
不要介意有趣的名字。这里的重点是继承链使用类型参数来实现编译时多态。不幸的是,这些模板的嵌套级别非常高。因此,缩写对于可读性和可维护性至关重要。
回答by Toji
is this use of typedef super common/rare/never seen in the code you work with?
在您使用的代码中,这种使用 typedef 是否超级常见/罕见/从未见过?
I have never seen this particular pattern in the C++ code I work with, but that doesn't mean it's not out there.
我从未在我使用的 C++ 代码中看到过这种特殊模式,但这并不意味着它不存在。
is this use of typedef super Ok (i.e. do you see strong or not so strong reasons to not use it)?
使用 typedef 是否超级好(即,您是否认为不使用它的强大或不那么强大的理由)?
It doesn't allow for multiple inheritance (cleanly, anyway).
它不允许多重继承(无论如何都是干净的)。
should "super" be a good thing, should it be somewhat standardized in C++, or is this use through a typedef enough already?
“超级”应该是一件好事,它应该在 C++ 中有些标准化,还是通过 typedef 已经足够了?
For the above cited reason (multiple inheritance), no. The reason why you see "super" in the other languages you listed is that they only support single inheritance, so there is no confusion as to what "super" is referring to. Granted, in those languages it IS useful but it doesn't really have a place in the C++ data model.
由于上述原因(多重继承),否。您在列出的其他语言中看到“super”的原因是它们只支持单继承,因此“super”指的是什么没有混淆。当然,在这些语言中它很有用,但它在 C++ 数据模型中并没有真正的位置。
Oh, and FYI: C++/CLI supports this concept in the form of the "__super" keyword. Please note, though, that C++/CLI doesn't support multiple inheritance either.
哦,仅供参考:C++/CLI 以“__super”关键字的形式支持这个概念。但请注意,C++/CLI 也不支持多重继承。
回答by James Hopkin
I've quite often seen it used, sometimes as super_t, when the base is a complex template type (boost::iterator_adaptor
does this, for example)
我经常看到它被使用,有时作为 super_t,当基础是一个复杂的模板类型时(boost::iterator_adaptor
例如这样做)