Attach multiple overlapping classes by overriding?

I was interested to learn about the following case, but I do not see enough terminology to find any answers anywhere.

Let's start with the general case: I have only 3 classes. 2 of them are inherited from the third and should be considered as specializations.

Now these 3 classes seem partially abstract and each of them introduces new pure virtual functions, because this β€œclass structure” can be implemented differently for different purposes. And each of these 3 classes gets access to pure virtual functions from the inside, so they cannot be implemented later.

Then there is a 4th class that inherits from the second in order to specialize the purpose of pure virtual functions of the second class. There is also a 5th grade that does the same for 3rd grade.

Now there are still pure virtual functions of the 1st class that need specialization in accordance with the 4th and 5th classes. This is where I am having some problems, and I might think of two ways to solve this problem that really do not satisfy me.

  • Have a 6th grade inherited from 1st grade and specialize in meeting the needs of 4th and 5th grade, and these classes inherit from 6th grade. This will lead to a "scary diamond."

enter image description here

  • Have a 6th grade that does not inherit from 1st grade, but which nonetheless implements a specialized assignment suitable for 4th and 5th grades. Then the 4th grade and the 5th grade inherit from the 6th and add the implementation of pure virtual functions of the 1st grade. These implementations do nothing but call the similar functions of the 6th, passing the same parameters, etc.

enter image description here

I am currently seeking a second solution, as I want to avoid the "diamond fear." But I don't like the extra implementation code that comes with it. Isn't there an easier way to combine different (interfaces /) classes?

For example, using the second solution, I thought of something like the same function prototypes in the 6th class as in the first class, and told the compiler that the 1st function should be redefined by the 6th class function. Unfortunately, using myfunction; inside a class declaration of 4th and 5th grade does not work.

Or asked in general: is there a way to join the "interfaces" - this means that a pure virtual function of a class can be defined by a completely different class if the prototype is the same and as long as they are both inherited from the child. I want to avoid duplicating code as much as possible, since I don't need β€œheavy” classes.

If this illustration is too abstract, I will give an example.

€ dit: Ask your opinion: what would be the best solution in this case?

+4
source share
2 answers

I would go with a solution that is very similar to the first:

  • Create 6th grade exactly as you described.
  • Now use the Bridge design template - enter the inner member in both 2 and 3 of type 1. Add a class 6 instance to this inner member.
  • Create a tunnel implementation for virtual methods that you lack in classes 4 and 5. The implementation should be single-line, which simply names the specific implementation of 6.

Hope this helps. If you need additional help, I will try to dwell on it in more detail.

===============

Following your comment, hope this helps:

Well, not quite. Take the first solution and remove the inheritance 6 of 4 and 5 (4 inherits 2 and 5 inherits 3 and what it is).

Class 6 inherits 1. Let the call of class 1 be Base. Add a Base member to both 4 & 5 classes (call by name).

Say class 4 is foo and class 2 is Base2. It will look something like this (sorry for the bad C ++ syntax, some time has passed since I wrote the actual C ++ code):

 class foo: Base2 { private Base* impl; public foo(Base* impl) { this.impl = impl; } void virtualMethod() { this.impl->virtualMethod() } } 
+1
source

The original idea came from Avi, but I don't know if this is the best solution. I will post it anyway to have a final thread

I will have a 6th grade interface as an aggregate of 1st grade. The actual type of aggregate will be controlled at the 4th level (4th / 5th class), where a constant dynamic instance of the corresponding class will be passed through the constructor calls to the 1st class. The pointer will be saved here. Although it will be a 7th grade pointer that defines an interface for the 6th grade only. I also made 1st grade a friend of 7th grade, so the interface will only be accessible from there.

enter image description here

+1
source

All Articles