In Java, I can easily have a parallel track of interface inheritance, and classes that both inherit and implement the interfaces:
public class Main {
interface I1 {
void f1();
};
interface I2 extends I1 {
void f2();
};
static class C1 implements I1 {
public void f1() {}
};
static class C2 extends C1 implements I1 {
public void f2() {}
};
public static void main(String[] args) {
C2 c2 = new C2();
}
}
This works just fine. However, trying the same thing in C++:
class I1 {
public:
virtual void f1() = 0;
};
class I2 : public I1 {
public:
virtual void f2() = 0;
};
class C1 : public I1 {
public:
void f1() override {}
};
class C2 : public I2, public C1 {
public:
void f2() override {}
};
int main()
{
C2* c2 = new C2;
}
fails with
cppscratch.cpp(20): error C2259: 'C2': cannot instantiate abstract class
cppscratch.cpp(14): message : see declaration of 'C2'
cppscratch.cpp(20): message : due to following members:
cppscratch.cpp(20): message : 'void I1::f1(void)': is abstract
on Visual C++ 16.10. Making all ABC inheritance virtual seems to help, but produces ominous warnings(once again, in Visual C++)
cppscratch.cpp(17,1): warning C4250: 'C2': inherits 'C1::C1::f1' via dominance
cppscratch.cpp(12): message : see declaration of 'C1::f1'
The answers to this post suggest that this is just fine and I can ignore the warning. Is it really acceptable do to this? No hidden "dread diamond" bugaboos waiting to bite me?
UPDATE: I've read several additional blog posts and SO questions, and there is considerable disagreement on whether virtual inheritance as a solution to the "dread diamond" is ever permissible. But some authors (Good and bad sides of virtual inheritance in C++) at least suggest that the one acceptable use is what he calls "mix ins" which are basically the same as Java interfaces. The one drawback seems to be the need to use dynamic_cast
which doesn't seem especially awful. So unless someone comes up with a more definitive reference saying yay or nay, I'm going to run with that.