我经常面对这个问题。假设我有以下类(class):

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

我看到我可以在B*中的A上有setter和getter,并在SuperA中覆盖它们以使用SuperB而不是B,并且从不直接引用B*并始终使用 setter/getter ,但这对于A似乎有点干扰。

尝试撰写,即拥有SuperA实例的A*看起来也不好。

如果A不拥有单个B*而是说一个std::vector<B*>,那就变得更加困难。

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

最佳答案

您可以让A具有一个 protected 构造函数,该构造函数采用B*:

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

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

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

关于c++ - C++中组合关系的继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27709146/

10-11 19:04