Наследование от защищенных классов в C +++
-
03-07-2019 - |
Вопрос
Предположим, у меня есть следующее заявление:
class Over1
{
protected:
class Under1
{
};
};
Я знаю, что мог бы сделать следующее:
class Over2 : public Over1
{
protected:
class Under2 : public Under1
{
};
};
Но есть ли способ объявить Under2 без Over2?
Поскольку вам пришлось бы расширить Over1, чтобы использовать любую производную от Under1, это может показаться глупым, но в данной ситуации может быть 30 различных вариантов Under.Я могу либо:
- Положите их все внутрь Поверх 1 :Не привлекательно, поскольку Over2 может использовать только 1 или 2 из них
- Положить их друг на своя версия по :Не привлекательно, так как тогда вам придется умножать наследование практически от того же класса.
- Найдите способ создавать детей младше 1 года без создания детей старше 1 года
Так возможно ли это?
Спасибо.
Решение
Используя шаблоны и явные специализации, вы можете сделать это всего лишь с одним дополнительным объявлением класса в Over1.
class Over1
{
protected:
class Under1
{
};
template <typename T>
class UnderImplementor;
};
struct Under2Tag;
struct Under3Tag;
struct Under4Tag;
template <>
class Over1::UnderImplementor<Under2Tag> : public Over1::Under1
{
};
template <>
class Over1::UnderImplementor<Under3Tag> : public Over1::Under1
{
};
template <>
class Over1::UnderImplementor<Under4Tag> : public Over1::Under1
{
};
Надеюсь, это поможет.
Другие советы
Лучше, чем создавать вложенные классы, возможно, вы захотите рассмотреть возможность встраивания этих закрытий в пространство имен.Таким образом, вам не нужен внешний класс, чтобы получить внутренний класс.Есть несколько веских аргументов "за" и "против" в Руководство по стилю Google C ++.
Если вы хотите сохранить защиту Under1, то по определению вам необходимо наследовать от Over1, чтобы получить к нему доступ.Я бы предложил сделать Under1 общедоступным или использовать пространства имен, как предложил Дуглас.
У меня нет компилятора, чтобы протестировать их прямо сейчас, поэтому я совсем не уверен, что это сработает, но вы могли бы попробовать это:
class Over1
{
protected:
class Under1
{
};
public:
class Under1Interface : public Under1
{
};
};
class Under2 : public Over1::Under1Interface
{
};
Или, возможно, что-то вроде этого:
class Over1
{
protected:
class Under1
{
};
};
class Under2 : private Over1, public Over1::Under1
{
};
Или даже:
class Under2;
class Over1
{
friend class Under2;
protected:
class Under1
{
};
};
class Under2 : public Over1::Under1
{
};
Хотя это выставило бы все личные данные Over1s на уровень Under2 - вряд ли это то, чего вы хотели бы.
По-моему, звучит немного обалденно с дизайном.Почему бы не попробовать структурировать свой код по-другому?Я думаю, что это могло бы быть хорошим кандидатом для шаблона decorator, где вы могли бы обернуть свой базовый класс в различные декораторы для достижения желаемой функциональности, различные варианты 'under' могли бы быть декораторами.Просто мысль, которую трудно сказать, не зная больше о намерениях вашего кода.