Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ multiple diamonds inheritance and pure virtual functions

Consider the following architecture:

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 {};
};

As such, BB and BBB are virtual classes, because f is not overridden by BB, and neither f nor g are by BBB. My wish is to be able to instantiate BB and BBB (so that BB and BBB use the override of f defined by B, and BBB uses the override of g defined by BB).

The question is: which inheritance relationships should be marked as virtual to instantiate BB and BBB ?

The inheritance diagram should ideally look like this:

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

The idea behind this design is that A, AA and AAA are interfaces describing incremental feature levels. B, BB and BB are one corresponding incremental implementation. (So that BB for instance defines everything needed by AA, and also features what's in B)

like image 259
Marsya Kaustentein Avatar asked Oct 17 '22 14:10

Marsya Kaustentein


1 Answers

if A AA AAA are really only interfaces, i mean they don't have any members, then you don't need any virtaul inheritance, implement only interfaces and call them from base classes. What you implemented in B for interface A, must be implemented also in BB, then call B:pureVirtual() in BB. Otherwise should be like this; (Then you should have a look at: '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 { }
};

Edit: (Without virtual inheritance)

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(); }
};
like image 96
Yusuf R. Karagöz Avatar answered Oct 21 '22 00:10

Yusuf R. Karagöz