#c #visual-c #gcc #macros
#c #visual-c #gcc #макросы
Вопрос:
Пожалуйста, скажите мне, есть ли способ вручную реализовать специфичный для Microsoft макрос __super…
Комментарии:
1. Пожалуйста, дайте нам знать, что делает макрос __super.
2. На самом деле
__super
это не макрос, а ключевое слово — msdn.microsoft.com/en-us/library/94dw1w7x (v = против 80).aspx3. @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
или подобного MSVCMyType
, особенно если он шаблонный. Это также обеспечивает хорошее единообразие для всех моих операторов. 🙂 Кроме того, я считаю, что шаблонные классы обычно непригодны для использования без такого 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, он должен быть закодирован вручную для каждой иерархии. :/