5

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)

1 Answers1

3

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(); }
};
  • But then `void g() override { BB::g(); }` is an override of g that just calls BB's override. Can't we just say that we want to directly use BB's definition of g ? So that the user implementing BBB is not tempted to tamper with g. – Marsya Kaustentein Mar 29 '17 at 11:11
  • @MarsyaKaustentein if you want to implement any other things in `BBB:g()` you can. if you don't want implement `g() and f()` in `BBB` no you can't. Because then it will be abstract class and you can't have `BBB` instances. – Yusuf R. Karagöz Mar 29 '17 at 11:15