从C +++中的受保护类继承

时间:2020-03-06 14:55:50  来源:igfitidea点击:

假设我有以下声明:

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

我知道我可以执行以下操作:

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

但是,有没有一种方法可以在没有Over2的情况下声明Under2?

由于我们必须扩展Over1才能使用Under1的任何派生类,因此这似乎很愚蠢,但是在这种情况下,可能会有30种不同的Under风格。我可以:

  • 将它们全部放到Over1内:不吸引人,因为Over2只能使用其中的1个或者2个
  • 将它们各自放在自己的Over版本中:自从那时以来,这种方法就没有吸引力了,我们将不得不从几乎相同的类中继承多个继承。
  • 找到一种方法来创建Under1的子代而不创建Over1的子代

那有可能吗?

谢谢。

解决方案

比创建嵌套类更好,我们可能希望查看将这些Clos嵌入到名称空间中。这样,我们不需要外部类即可获取内部类。 《 Google C ++样式指南》中有很多赞成和反对的观点。

使用模板和显式专业化,只需在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
{
};

希望这可以帮助。

如果要保护Under1,则根据定义,我们需要继承Over1才能对其进行访问。我建议将Under1公开,或者使用Douglas建议的名称空间。

我现在没有编译器可以对它们进行测试,因此我完全不确定它们是否可以工作,但是我们可以尝试以下方法:

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
{
};

尽管这会使Over1的所有私有对象暴露于Under2,但这并不是我们想要的。

在我看来,这听起来有点时髦。为什么不尝试以不同的方式构造代码。我认为这可能是装饰器模式的不错选择,我们可以将基类包装在各种装饰器中以实现所需的功能,"下面"的各种样式都可以作为装饰器。只是一个想法,在不了解代码意图的情况下很难说出来。