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?