C++中组合关系的继承

Red*_*ark 2 c++ inheritance composition

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

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;
};
Run Code Online (Sandbox Code Playgroud)

然后,我想扩展AB提供新信息.我敢肯定,SuperASuperB有一个"是"的有关系A,并B分别.直接的方法是尝试继承:

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;
};
Run Code Online (Sandbox Code Playgroud)

但这显然不是很好,因为SuperA实际上会有两个B:一个来自A班级,另一个来自SuperB班级.超越desc并不是那么优雅.

我可以看到,我能有getter和setter方法上B*A,并覆盖它们SuperA使用SuperB的不是B,决不是指以B*直接和经常使用的吸气剂,但是这似乎有点侵入了A.

试图撰写,即SuperA拥有一个A*实例也不会看起来更好.

如果A不是一个人B*而是一个发言权,那就变得更难了std::vector<B*>.

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

Bar*_*rry 5

你可能只有A一个受保护的构造函数,它接受B*:

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

protected:
    A(B* b)
    : _B(b)
    { }
};
Run Code Online (Sandbox Code Playgroud)

以便:

class SuperA : public A {
public:
    SuperA()
    : A(new SuperB)
    { }
};
Run Code Online (Sandbox Code Playgroud)