0

Topic may be confusing, so here's the code example (sandbox here):

class AbstractA {
 protected:
  int wibble_;
 public:
  AbstractA(int wibble) : wibble_(wibble) { }
  virtual ~AbstractA() { }
  virtual void DoThing(void) = 0;  // Pure virtual method.
};

class AbstractB : public virtual AbstractA {
 public:
  AbstractB(int wibble) : AbstractA(wibble) { }
  virtual ~AbstractB() { }
  virtual void DoOtherThing(void) = 0;  // Pure virtual method.
};

class DerivedA : public AbstractA {
 public:
  DerivedA(int wibble) : AbstractA(wibble) { }
  virtual ~DerivedA() { }
  virtual void DoThing(void) { wibble_ = 1; }  // Implement pure virtual method.
};

class DerivedB : public AbstractB {
 public:
  //DerivedB(int wibble) : AbstractB(wibble) { }  // Error -- see below.
  DerivedB(int wibble) : AbstractA(wibble), AbstractB(wibble) { }  // Works.
  virtual ~DerivedB() { }
  virtual void DoThing(void) { wibble_ = 2; }  // Implement AbstractA method.
  virtual void DoOtherThing(void) { wibble_ = 3; }  // Implement AbstractB method.
};

I have two abstract classes, AbstractA and AbstractB. AbstractB inherits from AbstractA using the virtual keyword, so DoThing() remains pure virtual. The AbstractB constructor calls the constructor for AbstractA, which initializes the wibble_ data member.

I then have two derived classes DerivedA and DerivedB. DerivedA inherits AbstractA, calls AbstractA(int) from its constructor, and implements AbstractA::DoThing(). Similarly, DerivedB inherits and implements AbstractB.

Here's the part I don't get. DerivedB doesn't inherit AbstractA directly. But the compiler insists that a call to a constructor of AbstractA is implicit in the constructor of DerivedB. If I try to use the first DerivedB constructor, commented out in the example, I get this error:

foo.h: In constructor 'DerivedB::DerivedB(int)':
foo.h:31:42: error: no matching function for call to 'AbstractA::AbstractA()'

So why is it necessary for DerivedB to call the constructor of a class (AbstractA) that its base class (AbstractB) inherited? I mean, AbstractB(int) calls AbstractA(int) in its initializer, so doesn't calling AbstractA(wibble), AbstractB(wibble) effectively call AbstractA(wibble) twice -- once directly, once from AbstractB()'s constructor?

Dana M
  • 198
  • 1
  • 11
  • 3
    *"`AbstractB` inherits from `AbstractA` using the `virtual` keyword, so `DoThing()` remains pure virtual."* These two facts are unrelated. `DoThing` would remain pure virtual with or without virtual inheritance. – Igor Tandetnik Aug 07 '18 at 01:31
  • @IgorTandetnik - Ah, thank you, yes, that's a good point. Also, thanks to folks for marking this as a duplicate. It was a matter of knowing exactly what sort of question I was trying to ask. – Dana M Aug 07 '18 at 15:01

0 Answers0