C ++中组合关系的继承

时间:2014-12-30 16:39:03

标签: 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;
};

然后,我想用新信息扩展AB。我确信SuperASuperB有一个&#34; is-a&#34;与AB的关系。直接的方法是尝试继承:

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实际上有两个B:来自A类的那个,另一个来自SuperB类。而desc的覆盖并不那么优雅。

我可以看到我可以在B*的{​​{1}}上设置设置者和获取者,并在A中覆盖它们以使用SuperA代替SuperB ,永远不要直接引用B并始终使用getter,但这似乎对B*有点干扰。

尝试撰写,即让A拥有SuperA个实例也不会更好。

如果A*不是一个A而是一个说B*,那就更难了。

这是一个常见问题吗?是否有一个我不明白的优雅解决方案?

1 个答案:

答案 0 :(得分:5)

你可以让A拥有一个受B*保护的构造函数:

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

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

那样:

class SuperA : public A {
public:
    SuperA()
    : A(new SuperB)
    { }
};
相关问题