【问题标题】:Inheritance of composition relationship in C++C++中组合关系的继承
【发布时间】:2014-12-30 16:39:03
【问题描述】:

我经常面对这个问题。假设我有这些课程:

class B
{
  public:
    virtual std::string className(){return "B";}
};

class A
{
  public:
    A()
    : _B(new B)
    {}

    virtual std::string className(){return "A";}

    virtual void desc()
    {
      std::cout << "I am " << className() << 
        " and I own: " << _B->className() << std::endl;
    }

  protected:
    B * _B;
};

然后,我想用新信息扩展AB。我确信SuperASuperB 分别与AB 具有“is-a”关系。直接的方法是尝试继承:

class SuperB: public B
{
  public:
    virtual std::string className(){return "SuperB";}
}

class SuperA: public A
{
  public:
    SuperA()
    : A()
    , _superB(new SuperB)
    {}

    virtual std::string className(){return "SuperA";}

    virtual void desc()
    {
      std::cout << "I am " << className() << 
        " and I own: " << _superB->className() << std::endl;
    }
  protected:
    SuperB * _superB;
};

但这显然不好,因为SuperA 实际上有两个Bs:一个来自A 类,另一个来自SuperB 类。而desc 的覆盖就没那么优雅了。

我可以看到我可以在 B* 中的 A 中设置 setter 和 getter,并在 SuperA 中覆盖它们以使用 SuperB 而不是 B,并且永远不要直接引用 B*并且总是使用 getter,但这对于 A 来说似乎有点干扰。

尝试编写,即让 SuperA 拥有一个 A* 实例看起来也不好。

如果A 拥有的不是一个B* 而是一个std::vector&lt;B*&gt;,那就更难了。

这是一个常见问题吗?有没有我看不到的优雅解决方案?

【问题讨论】:

  • 为什么你不能在A 中有一个接受B 指针的受保护的c'tor?然后用它来构造superAA子对象superB?
  • 您可以在SuperA 中使用_superB 的任何地方使用static_castdynamic_cast。不优雅,但可能足以满足您的目的?
  • @StoryTeller 这是一个解决方案。不过这对 A 来说有点麻烦。
  • 我认为解决问题的一种方法是 ASuperA 类有两个职责:它们分别将 BSuperB 适配到其他接口, 他们管理BSuperB 对象的生命周期。您可以通过仅提供转换 ctor A(B*) 等来拆分这些职责,然后提供另一种类型来管理这些对象的生命周期。
  • @RedWark,可能是这样,但恕我直言,这并不比从一开始就拥有一个受保护的成员更具侵入性。

标签: c++ inheritance composition


【解决方案1】:

你可以让A 有一个受保护的构造函数,它接受B*

class A {
public:
    A()
    : _B(new B)
    { }

protected:
    A(B* b)
    : _B(b)
    { }
};

这样:

class SuperA : public A {
public:
    SuperA()
    : A(new SuperB)
    { }
};

【讨论】:

  • 我没想到。这个解决方案实际上并不是那么具有侵入性,并且支持我在问题的后半部分中提到的向量!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多