Возможно ли реализовать макрос __super?

#c #visual-c #gcc #macros

#c #visual-c #gcc #макросы

Вопрос:

Пожалуйста, скажите мне, есть ли способ вручную реализовать специфичный для Microsoft макрос __super

Комментарии:

1. Пожалуйста, дайте нам знать, что делает макрос __super.

2. На самом деле __super это не макрос, а ключевое слово — msdn.microsoft.com/en-us/library/94dw1w7x (v = против 80).aspx

3. @Neil: msdn.microsoft.com/en-us/library/94dw1w7x.aspx

4. у вас есть конкретный вариант использования, который вы хотите решить? В общем, сложность предоставления полномасштабной __super реализации с пользовательским кодом будет слишком большой, но если вас интересует конкретный вариант использования, это может оказаться не таким сложным.

Ответ №1:

 class Base{
public:
  void func(){
    // something
  }
};

class Derived : public Base{
public:
  void func(){
    Base::func(); // just use the base class name
  }
};
  

Хотя я предполагаю, что это не то, что вы хотите, и вам нужен общий доступ для каждого класса? Я не знаю прямого решения, но вы всегда можете typedef использовать свой непосредственный базовый класс:

 class Derived : public Base{
  typedef Base super; // typedef accordingly in every class
public:
  void func(){
    super::func();
  }
};
  

Или даже иметь промежуточный класс только для typedef, если вы действительно хотите..

 template<class Base>
struct AddSuper : public Base {
protected:
  typedef Base super;
};

class Derived : public AddSuper<Base> {
public:
  void func(){
    super::func();
  }
};
  

Обратите внимание, что вы не должны забывать повторно вводить defв каждом производном классе, иначе вы получите дыры в вашей цепочке вызовов.

Один недостаток: вся конструкция разбивается на несколько базовых классов. :/

Комментарии:

1. @Ryan: Приятным побочным эффектом от typedef является то, что вы можете использовать его в списке инициализаторов вместо (возможно, длинного) имени базового класса. 🙂

2. Я использовал typedef трюк (без дополнительного промежуточного звена) несколько раз при наследовании от классов с аргументами шаблона. DRY на работе … (или почти, поскольку вам нужно повторить один раз).

3. @Matthieu: Обычно я делаю это для текущего класса с помощью this_type или self_type или подобного MSVC MyType , особенно если он шаблонный. Это также обеспечивает хорошее единообразие для всех моих операторов. 🙂 Кроме того, я считаю, что шаблонные классы обычно непригодны для использования без такого typedef .

Ответ №2:

Избегайте этого, это делает ваш код непереносимым. Если вы хотите иметь короткое имя для своего базового класса, тогда используйте typedef:

 class Derived: public BaseWithALongName
{
   typedef BaseWithALongName super;
};
  

Ответ №3:

Ключевое слово super на самом деле было предложено давным-давно в процессе стандартизации C , но оно было отвергнуто за ненадобностью, поскольку его можно было реализовать с использованием метода, описанного Xeo в его ответе — это описано в книге Страуструпа D amp; E. Я предполагаю, что Microsoft решила, что это действительно необходимо, но имейте в виду, что если вы будете использовать его, ваш код не будет переносимым.

Комментарии:

1. Одна хорошая особенность __super ключевого слова, которую вы не можете эмулировать, заключается в том, что оно учитывает все базовые классы.

2. @Xeo: вопрос в том, чтобы сделать код немного более громоздким… вы можете написать шаблон адаптера, который будет наследоваться от всех базовых классов и добавит using X::func; для каждого базового класса X . Тогда наиболее производный класс должен наследовать только от этого адаптера. Если вы его вызовете, super то синтаксис: super::func будет отправлен непосредственному родителю, который будет иметь using объявления и будет учитывать все базовые классы. Все еще слишком сложно для получения практически никакого эффекта.

3. @David: Хотя это интересная идея, спасибо за это. Но вы правы. У вас не может быть такого адаптера, как simple mixin, он должен быть закодирован вручную для каждой иерархии. :/