There is a class FooBase which has a method FunBase (). From this class, two classes, FooA and FooB, are inherited through virtual inheritance. In FooB, the FunBase () method is removed, because it cannot be there according to the logic of the program. From these two classes, the class FooEnd is inherited in which the FunBase () method should be. How to change the code so that the FooEnd object would be possible to call the FunBase () method without using aggregation.

using std::cout; using std::endl; class FooBase { public: void FunBase() { cout << "FunBase" << endl; } }; class FooA: virtual public FooBase { public: void FunA() { cout << "FunA" << endl; } }; class FooB: virtual public FooBase { public: void FunB() { cout << "FunB" << endl; } void FunBase() = delete; }; class FooEnd: public FooA, public FooB { public: void FunEnd() { cout << "FunEnd" << endl; } }; int main() { FooEnd bat; bat.FunBase(); return 0; } 

By aggregation, I mean a record of the form:

 class FooEnd: public FooA, public FooB { public: void FunEnd() { cout << "FunEnd" << endl; } void FunBase() { FooBase::FunBase(); }; }; 
  • Explain to me what the inheritance can be (i.e., the relation IS), in which there should not be some functionality that exists in the base class? Are you sure that you need inheritance is not just because you like how this term sounds? - Harry
  • @Harry yes, 100% sure. The base class here contains resources and is virtual (I apologize for not displaying this in the example). Its object cannot be created so that the Barbara Liskov principle is preserved (although no, it cannot be stored if you use a pointer to FooBase -_-). At the same time, FunBase must be implemented in the base class because many more will be inherited from it. If FunBase is implemented above the tree of inheritance, you get a lot of its implementations, which is unacceptable (one change in the method will have to be duplicated everywhere). - mrFieldy
  • @Harry That would be clearer, let me try to give an example. On a specific platform, there is an abstract port in which, in addition to the interface, certain resources and methods are defined that are the same for all such ports on this platform. And there are three implementations of it: an input port which (is) a port. output port which is also a port. And input \ output is a port that can work in both modes and (is) both input and output. The problem is that in the output port, some of the open methods of the abstract port are unnecessary (for example, an interrupt listener that every port must have). - mrFieldy

1 answer 1

You can do this:

 class FooB: virtual public FooBase { public: void FunB() { cout << "FunB" << endl; } protected: using FooBase::FunBase; }; class FooEnd: public FooA, public FooB { public: void FunEnd() { cout << "FunEnd" << endl; } using FooBase::FunBase; }; 

PS I think that if there is such a desire, then something is wrong with the design of classes, so I recommend still thinking how to do it in a human way.

  • Thank you very much for your answer. Only instead of your version I did using FooBase :: FunBase in the FooEnd class, but the essence remained the same. - mrFieldy
  • The most useful thing is PS - AR Hovsepyan
  • I thought well last night and this morning. You and Harry are right. I understood how to rebuild. Thanks you. - mrFieldy