C++多重菱形继承和纯虚函数

5
考虑以下架构:
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都是虚类,因为BB没有覆盖f函数,而BBB没有覆盖f和g函数。我的愿望是能够实例化BB和BBB(这样BB和BBB将使用由B定义的f函数的重写,而BBB将使用由BB定义的g函数的重写)。
问题是:哪些继承关系应标记为`virtual`以实例化`BB`和`BBB`?
理想情况下,继承图应如下所示:
A
|\
| \
|  \
AA   B
| \  |
|  \ |
AAA  BB
  \  |
   \ |
     BBB

这个设计的理念是,A、AA和AAA是描述增量功能级别的接口。B、BB和BB是相应的增量实现。(例如,BB定义了AA所需的所有内容,并具有B中的功能)

你在类定义中缺少虚拟修饰符,我认为否则你的整个问题就没有意义了。细节很重要。 - Vincent Fourmond
当然,我是指函数的虚拟修饰符。 - Vincent Fourmond
1个回答

3
如果A AA AAA只是接口,也就是它们没有任何成员,那么你不需要使用虚继承,只需实现接口并从基类中调用它。在接口A中实现的内容,在BB中也必须实现,然后在BB中调用B:pureVirtual()。否则,应该像这样实现;(然后您应该查看:'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(); }
};

但是 void g() override { BB::g(); } 是对 g 的重写,只是调用了 BB 的重写。我们不能直接使用 BB 对 g 的定义吗?这样实现 BBB 的用户就不会试图篡改 g 了。 - Marsya Kaustentein
@MarsyaKaustentein 如果你想在 BBB:g() 中实现其他功能,可以这样做。但如果你不想在 BBB 中实现 g()f(),那么就不行了。因为这样它将成为抽象类,你将无法创建 BBB 实例。 - Yusuf R. Karagöz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接