I've read on many places that Java's interface can be 100% emulated using C++'s abstract class with all pure virtual methods.
I'm trying to convert this piece of java code:
interface A {
void a();
}
interface B extends A {
void b();
}
class C implements A {
public void a() {
}
}
class D extends C implements B {
public void b() {
}
}
D d = new D();
d.a();
d.b();
into something like this in C++:
class A {
public:
virtual void a() const = 0;
protected:
virtual ~A() {
}
};
class B : public A {
public:
virtual void b() const = 0;
protected:
virtual ~B() {
}
};
class C : public /*implements*/ A {
public:
virtual void a() const override {
}
};
class D : public /*extends*/ C, public /*implements*/ B {
public:
virtual void b() const override {
}
};
D d;
d.a();
d.b();
but no matter how hard I try, I always end up with C++ complaining about ambiguity and/or missing body definitions.
The idea is that I want to derive from "C" which contains some shared code for all classes (here: "D" but there's more of them) and yet maintain the promise that "D" is 100% interchangeable with any class implementing "B" (incl. the parts from "A").
The errors I'm getting with C++ code above is:
../untitled1/main.cpp: In function ‘int main(int, char**)’:
../untitled1/main.cpp:39:7: error: cannot declare variable ‘d’ to be of abstract type ‘D’
D d;
^
../untitled1/main.cpp:28:7: note: because the following virtual functions are pure within ‘D’:
class D : public /*extends*/ C, public /*implements*/ B {
^
../untitled1/main.cpp:7:18: note: virtual void A::a() const
virtual void a() const = 0;
^
../untitled1/main.cpp:40:7: error: request for member ‘a’ is ambiguous
d.a();
^
../untitled1/main.cpp:7:18: note: candidates are: virtual void A::a() const
virtual void a() const = 0;
^
../untitled1/main.cpp:23:18: note: virtual void C::a() const
virtual void a() const override {
^
In C++ programming there is no built-in concept of interfaces. In order to create an interface, we need to create an abstract class which is having only pure virtual methods.
Unless the class that implements the interface is abstract, all the methods of the interface need to be defined in the class. An interface can contain any number of methods.
Yes, it is possible. This is the catch: java does not support multiple inheritance, i.e. class cannot extend more than one class. However class can implement multiple interfaces.
If the module containing the interface is compiled at a different time than the module containing the implementation, you can add a new method to the interface without it being aware that it's breaking an external module.
This is a problem that is solved by virtual inheritance from A
.
class A {
public:
virtual void a() const = 0;
protected:
virtual ~A() {
}
};
class B : public virtual A {
public:
virtual void b() const = 0;
protected:
virtual ~B() {
}
};
class C : public virtual A {
public:
virtual void a() const override {
}
};
class D : public C, public B {
public:
virtual void b() const override {
}
};
The problem is that unless you specify that both C
and B
need to share an A
sub-object (all derived classes contain their bases as sub-objects), the two sub-objects you get from inheriting both B
and C
will be unrelated.
In your original scheme, the implementation provided by C
to the pure virtual member in A
wasn't considered as an implementation for the same function required by the A
in B
.
Since now there is only one A
sub-object, this problem goes away. But note that virtual inheritance is not without a price. So think if you really want to go with such a design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With