Наследование от защищенных классов в C +++ - PullRequest
3 голосов
/ 30 сентября 2008

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

class Over1
{
   protected:
      class Under1
      {
      };
};

Я знаю, что могу сделать следующее:

class Over2 : public Over1
{
   protected:
        class Under2 : public Under1
        {
        };
};

Но есть ли способ объявить Under2 без Over2?

Поскольку вам придется расширить Over1, чтобы использовать любую производную Under1, это может показаться глупым, но в этой ситуации может быть 30 различных разновидностей Under. Я могу либо:

  • Поместите их все в Over1: Не привлекательным, так как Over2 может использовать только 1 или 2 из них
  • Положите их каждый в их собственная версия Over: Not привлекательным с тех пор у вас будет умножить наследовать от почти тот же класс.
  • Найди способ создать дети Under1 без создания дети старше 1

Так возможно ли это?

Спасибо.

Ответы [ 4 ]

1 голос
/ 30 сентября 2008

Используя шаблоны и явные специализации, вы можете сделать это только с одним дополнительным объявлением класса в 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
{
};

Надеюсь, это поможет.

1 голос
/ 30 сентября 2008

Лучше, чем создавать вложенные классы, вы можете захотеть взглянуть на встраивание этих замыканий в пространство имен. Таким образом, вам не нужен внешний класс для того, чтобы получить внутренний класс. В Руководстве по стилю Google C ++ .

есть несколько веских аргументов за и против.
0 голосов
/ 09 июня 2009

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

0 голосов
/ 30 сентября 2008

Если вы хотите сохранить 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
{
};

Хотя это могло бы раскрыть все ряды Овер1 для Under2 - маловероятно, что вы захотите.

...