Bjarne Stroustrup упоминает в Дизайн и Эволюция C++ , что super
, поскольку ключевое слово рассмотрел комитет по Стандартам C++ ISO в первый раз, когда C++ был стандартизирован.
Dag Bruck предложил это расширение, назвав базовый класс "наследованным". Предложение упомянуло проблему множественного наследования и отметит неоднозначное использование. Даже Stroustrup был убежден.
После обсуждения, Dag Bruck (да, тот же человек, вносящий предложение), записал, что предложение было реализуемо, технически звучите, и свободный от главных дефектов и обработанного множественного наследования. С другой стороны, не было достаточного количества удара для маркера, и комитет должен решить более тернистую проблему.
Michael Tiemann прибыл поздно, и затем показал, что typedef'ed супер будет работать просто великолепно, с помощью той же техники, о которой спросили в этом сообщении.
Так, нет, это никогда не будет, вероятно, стандартизироваться.
, Если у Вас нет копии, , Дизайн и Эволюция определенно стоят указанной на обложке цены. Используемые копии могут иметься приблизительно за 10$.
Я использую __ супер ключевое слово. Но это - конкретная Microsoft:
Я время от времени использую это. Как раз в то самое время, когда я вывожу тип базового класса пару раз, я заменю его определением типа, подобным Вашему.
я думаю, что это может быть хорошее использование. Как Вы говорите, если Ваш базовый класс является шаблоном, он может сохранить ввод. Кроме того, шаблонные классы могут взять аргументы, которые действуют как политики для того, как шаблон должен работать. Вы свободны изменить базовый тип, не имея необходимость ремонтировать все Ваши ссылки на него, пока интерфейс основы остается совместимым.
я думаю, что использование посредством определения типа достаточно уже. Я не вижу, как это было бы встроено в язык так или иначе, потому что несколько, которых означает наследование, могут быть многими базовыми классами, таким образом, Вы можете определение типа это, поскольку Вы считаете целесообразным для класса, который Вы логически чувствуете, самый важный базовый класс.
Я не знаю, редко ли это или нет, но я, конечно, сделал то же самое.
, Как был указан, трудность с созданием этой части самого языка состоит в том, когда класс использует множественное наследование.
Одна дополнительная причина использовать определение типа для суперкласса состоит в том при использовании сложных шаблонов в наследовании объекта.
, Например:
template <typename T, size_t C, typename U>
class A
{ ... };
template <typename T>
class B : public A<T,99,T>
{ ... };
В классе B это было бы идеально для имения определения типа для иначе, Вы застрянете, повторяя его везде, Вы хотели сослаться на членов A.
В этих случаях это может работать со множественным наследованием также, но у Вас не было бы определения типа названным 'супер', это назовут 'base_A_t' или чем-то как этот.
- jeffk ++
После миграции от Turbo Pascal до C++ назад в день, я раньше делал это для имения эквивалента для "наследованного" ключевого слова Turbo Pascal, которое работает тот же путь. Однако после программирования в C++ в течение нескольких лет я прекратил делать его. Я нашел, что мне просто не был нужен он очень.
Я видел эту идиому, используемую во многих кодах, и я вполне уверен, я даже видел его где-нибудь в библиотеках Повышения. Однако, насколько я помню, что наиболее распространенное имя base
(или Base
) вместо super
.
Эта идиома особенно полезна при работе с шаблонными классами. Как пример, рассмотрите следующий класс (от реальный проект ):
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;
// …
}
не возражают против забавных имен. Важный момент здесь - то, что цепочка наследования использует аргументы типа для достижения полиморфизма времени компиляции. К сожалению, уровень вложенности этих шаблонов становится довольно высоким. Поэтому сокращения крайне важны для удобочитаемости и пригодности для обслуживания.
Я не вспоминаю наблюдение этого прежде, но на первый взгляд мне нравится оно. Как примечания Ferruccio, это не работает хорошо перед лицом MI, но MI является больше исключением, чем правило и нет ничего, что говорит, что что-то должно быть применимым везде, чтобы быть полезным.
действительно ли это использование определения типа супер общее/редко/никогда замеченный в коде, с которым Вы работаете?
я никогда не видел этот конкретный шаблон в коде C++, с которым я работаю, но это не означает, что это не там.
это использование определения типа супер хорошо (т.е. Вы видите сильный или не так веские причины не использовать его)?
Это не допускает множественное наследование (чисто, так или иначе).
должна "супер" быть хорошая вещь, она должна быть несколько стандартизирована в C++, или достаточно уже является этим использованием посредством определения типа?
По вышеупомянутой процитированной причине (множественное наследование), нет. Причина, почему Вы видите "супер" на других языках, что перечислили, состоит в том, что они только поддерживают единичное наследование, таким образом, нет никакого беспорядка относительно того, что "супер" относится к. Предоставленный, на тех языках это полезно, но это действительно не имеет места в модели данных C++.
, О, и к вашему сведению: C++ / CLI поддерживает это понятие в форме "__ супер" ключевое слово. Обратите внимание, тем не менее, что C++ / CLI не поддерживает множественное наследование также.
Супер (или наследованный) Очень Хорошая Вещь, потому что, если необходимо засунуть другой слой наследования промежуточная Основа и Полученный, только необходимо изменить две вещи: 1. "класс Основа: нечто" и 2. определение типа
, Если я вспоминаю правильно, комитет по Стандартам C++, рассматривало добавление ключевого слова для этого..., пока Michael Tiemann не указал, что это определение типа обманывает работы.
Что касается множественного наследования, так как это находится под контролем программиста, можно сделать то, что Вы хотите: возможно, super1 и super2, или что бы то ни было.
FWIW Microsoft добавил расширение для __ супер в их компиляторе.
Одна проблема с этим состоит в том, что, если Вы забываете к (пере-) определяют супер для производных классов, тогда любой вызов к супер:: что-то скомпилирует прекрасный, но вероятно не вызовет желаемую функцию.
, Например:
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 в комментариях к этому ответу, эта проблема может быть устранена путем создания определения типа частным, а не общедоступным или защищенным.)
Я всегда использовал "наследованный", а не супер. (Вероятно, из-за истории Дельфи), и я всегда делаю его частным , для предотвращения проблемы, когда 'наследованный' ошибочно опущен от класса, но подкласс пытается использовать его.
class MyClass : public MyBase
{
private: // Prevents erroneous use by other classes.
typedef MyBase inherited;
...
Мой стандарт 'шаблон кода' для создания новых классов включает определение типа, таким образом, я не имею возможности случайно опускать его.
я не думаю цепочечное "супер:: супер" предложение является хорошей идеей - при выполнении этого Вы, вероятно, связаны очень трудно к конкретной иерархии, и изменение его, вероятно, повредит материал плохо.
Я довольно часто видел, что это использовало, иногда как super_t, когда основой является сложный шаблонный тип (boost::iterator_adaptor
, делает это, например)