C ++多钻石继承和纯虚函数

时间:2017-03-29 09:55:54

标签: c++ interface multiple-inheritance virtual-functions diamond-problem

考虑以下架构:

class A  //abstract interface
{
    public:
    virtual void f() = 0;
};
class AA : public A  //abstract interface
{
    public:
    virtual void g() = 0;
}; 
class AAA : public AA  //abstract interface
{
    public:
    virtual void h() = 0;
}; 

class B :  public A // implementation class
{
    public:
    void f() override {};
};
class BB : public B, public AA {}; // implementation class
{
    public:
    void g() override {};
};
class BBB : public BB, public AAA {}; // implementation class
{
    public:
    void h() override {};
};

因此,BBBBB是虚拟类,因为f不会被BB覆盖,并且f和g都不是BBB。我希望能够实例化BB和BBB(这样BB和BBB使用B定义的f的覆盖,而BBB使用BB定义的g的覆盖)。

问题是:应将哪些继承关系标记为virtual以实例化BBBBB

继承图理想情况应如下所示:

A
|\
| \
|  \
AA   B
| \  |
|  \ |
AAA  BB
  \  |
   \ |
     BBB

这种设计背后的想法是A,AA和AAA是描述增量功能级别的接口。 B,BB和BB是一个相应的增量实现。 (因此BB例如定义了AA所需的一切,并且还具有B)中的特征

1 个答案:

答案 0 :(得分:3)

如果A AA AAA实际上只是接口,我的意思是它们没有任何成员,那么你不需要任何virtaul继承,只实现接口并从基类调用它们。您在B中为接口A实现的内容也必须在BB中实现,然后在B:pureVirtual()中调用BB。否则应该是这样的; (那你应该看一下:'class1' : inherits 'class2::member' via dominance

class A
{
public:
  virtual void f() = 0;
};
class AA : virtual public A
{
public:
  virtual void g() = 0;
};
class AAA : virtual public AA
{
public:
  virtual void h() = 0;
};

class B : virtual public A
{
public:
  void f() override { }
};
class BB : public B, virtual public AA
{
public:
  void g() override { }
};
class BBB : public BB, public AAA
{
public:
  void h() override { }
};

编辑:(没有虚拟继承)

class A  //abstract interface
{
public:
  virtual void f() = 0;
};
class AA : public A  //abstract interface
{
public:
  virtual void g() = 0;
};
class AAA : public AA  //abstract interface
{
public:
  virtual void h() = 0;
};

class B : public A // implementation class
{
public:
  void f() override {}
};
class BB : public B, public AA // implementation class
{
public:
  void g() override {}
  void f() override { B::f(); }
};
class BBB : public BB, public AAA // implementation class
{
public:
  void h() override {}

  void g() override { BB::g(); }
  void f() override { BB::f(); }
};