Использование “супер” в C++

192
задан paercebal 16 July 2011 в 20:27
поделиться

14 ответов

Bjarne Stroustrup упоминает в Дизайн и Эволюция C++ , что super, поскольку ключевое слово рассмотрел комитет по Стандартам C++ ISO в первый раз, когда C++ был стандартизирован.

Dag Bruck предложил это расширение, назвав базовый класс "наследованным". Предложение упомянуло проблему множественного наследования и отметит неоднозначное использование. Даже Stroustrup был убежден.

После обсуждения, Dag Bruck (да, тот же человек, вносящий предложение), записал, что предложение было реализуемо, технически звучите, и свободный от главных дефектов и обработанного множественного наследования. С другой стороны, не было достаточного количества удара для маркера, и комитет должен решить более тернистую проблему.

Michael Tiemann прибыл поздно, и затем показал, что typedef'ed супер будет работать просто великолепно, с помощью той же техники, о которой спросили в этом сообщении.

Так, нет, это никогда не будет, вероятно, стандартизироваться.

, Если у Вас нет копии, , Дизайн и Эволюция определенно стоят указанной на обложке цены. Используемые копии могут иметься приблизительно за 10$.

140
ответ дан Max Lybbert 23 November 2019 в 05:31
поделиться

Я использую __ супер ключевое слово. Но это - конкретная Microsoft:

http://msdn.microsoft.com/en-us/library/94dw1w7x.aspx

0
ответ дан Mark Ingram 23 November 2019 в 05:31
поделиться

Я время от времени использую это. Как раз в то самое время, когда я вывожу тип базового класса пару раз, я заменю его определением типа, подобным Вашему.

я думаю, что это может быть хорошее использование. Как Вы говорите, если Ваш базовый класс является шаблоном, он может сохранить ввод. Кроме того, шаблонные классы могут взять аргументы, которые действуют как политики для того, как шаблон должен работать. Вы свободны изменить базовый тип, не имея необходимость ремонтировать все Ваши ссылки на него, пока интерфейс основы остается совместимым.

я думаю, что использование посредством определения типа достаточно уже. Я не вижу, как это было бы встроено в язык так или иначе, потому что несколько, которых означает наследование, могут быть многими базовыми классами, таким образом, Вы можете определение типа это, поскольку Вы считаете целесообразным для класса, который Вы логически чувствуете, самый важный базовый класс.

1
ответ дан Scott Langham 23 November 2019 в 05:31
поделиться

Я не знаю, редко ли это или нет, но я, конечно, сделал то же самое.

, Как был указан, трудность с созданием этой части самого языка состоит в том, когда класс использует множественное наследование.

1
ответ дан Matt Dillard 23 November 2019 в 05:31
поделиться

Одна дополнительная причина использовать определение типа для суперкласса состоит в том при использовании сложных шаблонов в наследовании объекта.

, Например:

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 ++

3
ответ дан jdkoftinoff 23 November 2019 в 05:31
поделиться

После миграции от Turbo Pascal до C++ назад в день, я раньше делал это для имения эквивалента для "наследованного" ключевого слова Turbo Pascal, которое работает тот же путь. Однако после программирования в C++ в течение нескольких лет я прекратил делать его. Я нашел, что мне просто не был нужен он очень.

2
ответ дан Greg Hewgill 23 November 2019 в 05:31
поделиться

Я видел эту идиому, используемую во многих кодах, и я вполне уверен, я даже видел его где-нибудь в библиотеках Повышения. Однако, насколько я помню, что наиболее распространенное имя 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;
    // …
}

не возражают против забавных имен. Важный момент здесь - то, что цепочка наследования использует аргументы типа для достижения полиморфизма времени компиляции. К сожалению, уровень вложенности этих шаблонов становится довольно высоким. Поэтому сокращения крайне важны для удобочитаемости и пригодности для обслуживания.

8
ответ дан Konrad Rudolph 23 November 2019 в 05:31
поделиться

Я не вспоминаю наблюдение этого прежде, но на первый взгляд мне нравится оно. Как примечания Ferruccio, это не работает хорошо перед лицом MI, но MI является больше исключением, чем правило и нет ничего, что говорит, что что-то должно быть применимым везде, чтобы быть полезным.

11
ответ дан Community 23 November 2019 в 05:31
поделиться

действительно ли это использование определения типа супер общее/редко/никогда замеченный в коде, с которым Вы работаете?

я никогда не видел этот конкретный шаблон в коде C++, с которым я работаю, но это не означает, что это не там.

это использование определения типа супер хорошо (т.е. Вы видите сильный или не так веские причины не использовать его)?

Это не допускает множественное наследование (чисто, так или иначе).

должна "супер" быть хорошая вещь, она должна быть несколько стандартизирована в C++, или достаточно уже является этим использованием посредством определения типа?

По вышеупомянутой процитированной причине (множественное наследование), нет. Причина, почему Вы видите "супер" на других языках, что перечислили, состоит в том, что они только поддерживают единичное наследование, таким образом, нет никакого беспорядка относительно того, что "супер" относится к. Предоставленный, на тех языках это полезно, но это действительно не имеет места в модели данных C++.

, О, и к вашему сведению: C++ / CLI поддерживает это понятие в форме "__ супер" ключевое слово. Обратите внимание, тем не менее, что C++ / CLI не поддерживает множественное наследование также.

4
ответ дан Toji 23 November 2019 в 05:31
поделиться

Супер (или наследованный) Очень Хорошая Вещь, потому что, если необходимо засунуть другой слой наследования промежуточная Основа и Полученный, только необходимо изменить две вещи: 1. "класс Основа: нечто" и 2. определение типа

, Если я вспоминаю правильно, комитет по Стандартам C++, рассматривало добавление ключевого слова для этого..., пока Michael Tiemann не указал, что это определение типа обманывает работы.

Что касается множественного наследования, так как это находится под контролем программиста, можно сделать то, что Вы хотите: возможно, super1 и super2, или что бы то ни было.

14
ответ дан Colin Jensen 23 November 2019 в 05:31
поделиться

FWIW Microsoft добавил расширение для __ супер в их компиляторе.

18
ответ дан krujos 23 November 2019 в 05:31
поделиться

Одна проблема с этим состоит в том, что, если Вы забываете к (пере-) определяют супер для производных классов, тогда любой вызов к супер:: что-то скомпилирует прекрасный, но вероятно не вызовет желаемую функцию.

, Например:

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 в комментариях к этому ответу, эта проблема может быть устранена путем создания определения типа частным, а не общедоступным или защищенным.)

35
ответ дан 3 revs 23 November 2019 в 05:31
поделиться

Я всегда использовал "наследованный", а не супер. (Вероятно, из-за истории Дельфи), и я всегда делаю его частным , для предотвращения проблемы, когда 'наследованный' ошибочно опущен от класса, но подкласс пытается использовать его.

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

Мой стандарт 'шаблон кода' для создания новых классов включает определение типа, таким образом, я не имею возможности случайно опускать его.

я не думаю цепочечное "супер:: супер" предложение является хорошей идеей - при выполнении этого Вы, вероятно, связаны очень трудно к конкретной иерархии, и изменение его, вероятно, повредит материал плохо.

97
ответ дан Roddy 23 November 2019 в 05:31
поделиться

Я довольно часто видел, что это использовало, иногда как super_t, когда основой является сложный шаблонный тип (boost::iterator_adaptor, делает это, например)

3
ответ дан James Hopkin 23 November 2019 в 05:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: