I have this, maybe a little bit complex class hierarchy:
class BS {
public:
virtual void meth()=0;
};
class BCA : public virtual BS {
};
class BSS : public virtual BS {
};
class BCS : public virtual BCA, public virtual BSS {
};
class BI4 {
public:
void meth() {};
};
class BT4 : public virtual BI4, public virtual BSS {
};
class T4 : public virtual BCS, public virtual BT4 {
};
int main() {
T4 t4;
};
Now the problem is that although the void meth()
is available in the inheritance graph, despite this code won't compile:
$ g++ -c t.cc -std=c++11
t.cc: In function ‘int main()’:
t.cc:27:6: error: cannot declare variable ‘t4’ to be of abstract type ‘T4’
T4 t4;
^
t.cc:23:7: note: because the following virtual functions are pure within ‘T4’:
class T4 : public virtual BCS, public virtual BT4 {
^
t.cc:3:18: note: virtual void BS::meth()
virtual void meth()=0;
^
t.cc:3:18: note: virtual void BS::meth()
It seems to me as if BS
somehow wouldn't see the overloaded meth()
method through the BS->BCA->BCS->T4->BT4->BI4 chain.
But why? The method is clearly available, the C3 linearization algorithm used by the C++ should be able very clearly find it.
There are two main aspects:
BI4
class doesn't have BS
as a base class, it can't override anything from BS
.Example:
struct Base
{
virtual void foo() = 0;
};
#ifdef GOOD
struct Impl_foo: virtual Base
{
void foo() override {}
};
#else
struct Impl_foo
{
virtual void foo() {}
};
#endif
struct Abstract_derived: virtual Base
{};
struct Derived
: Abstract_derived
, Impl_foo // Java-like implementation inheritance.
// In C++ called "by dominance".
{};
auto main()
-> int
{
Derived o;
o.foo();
}
Without defining the GOOD
macro symbol, this code doesn't compile.