Overlapping java-like interfaces in C ++

I read in many places that the Java interface can be 100% emulated using the C ++ abstract class with all the pure virtual methods.

I am 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(); da(); db(); 

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; da(); db(); 

but no matter how hard I try, I always end up complaining about ambiguity and / or missing body definitions.

The idea is that I want to get from "C", which contains some common code for all classes (here: "D", but there are more), and still keep the promise that "D" is 100% interchangeable with any a class that implements "B" (including parts from "A").

Errors I get with C ++ code above:

 ../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 da(); ^ ../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 { ^ 
+5
source share
2 answers

This is a problem 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 if you do not specify that both C and B should share a sub-object of A (all derived classes contain their bases as sub-objects), two sub-objects from which you get inheritance as B , so C will not be relevant.

In the original scheme, the implementation provided by C pure virtual member in A was not considered as an implementation for the same function that is required for A in B

Since there is now only one sub-object A , this problem disappears. But note that virtual inheritance is not without price. So think about whether you really want to go with such a design.

+9
source

All you need is an implementation of class () in class D:

 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: void b() const override { } void a() const { C::a(); } }; int main() { D d; da(); db(); return 0; } 
0
source

Source: https://habr.com/ru/post/1269467/


All Articles