Вопрос

Предположим, у меня есть следующее заявление:

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' могли бы быть декораторами.Просто мысль, которую трудно сказать, не зная больше о намерениях вашего кода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top