1

Suppose I have an interface class and a partial implementation class. Also, suppose that I absolutely do not want this partial implementation to inherit from the interface:

class interface {
    virtual void fnA() const = 0; 
    virtual void fnB() const = 0; 
};

class partialImplementation { //Do not want to inherit from interface!
    void fnA() const {cout << "fnA from partial implementation" << endl;}
    //fnB() not implemented
};

The idea is that I'm planning to make several new classes all inheriting the interface, but I want to implement the same fnA() in each one. So, after inheriting the interface, maybe I could also inherit the partial implementation and hope that fnA() gets implemented. For example,

class myClass : interface, partialImplementation {
    //would like fnA() to be implemented by partialImplementation
    void fnB() const {cout << "fnB from myClass" << endl;} 
};

Of course, if you try to instantiate this class, you get this error:

main.cpp: In function 'int main()':
main.cpp:235:10: error: cannot declare variable 'm' to be of abstract type 'myClass'
main.cpp:201:7: note:   because the following virtual functions are pure within 'myClass':
main.cpp:193:15: note:  virtual void interface::fnA() const
Compilation failed.

After reading some other stackoverflow posts (like this one) it seems the only available solution is to do this:

class myClass : interface, partialImplementation {
    public:
    void fnB() const {cout << "fnB from myClass" << endl;} 
    void fnA() const {
        partialImplementation::fnA();
    }
};

In the linked post, the OP didn't mind typing three extra lines. But you could imagine that I actually want partialImplementation to implement more than just one function, and that I could be typing this same boilerplate over and over every time I want to make a new class inheriting this interface.

Does anyone know a way to do this without requiring partialImplementation to inherit from interface?

Marco Merlini
  • 875
  • 7
  • 29
  • This is the simplest and most obvious way of doing this. Its explicit. That's better. – Matthieu Brucher Feb 03 '19 at 17:58
  • 2
    Yes, what is wrong with having `partialImplementation ` inherit from `interface`? – Paul Sanders Feb 03 '19 at 18:04
  • BTW, if you do not inherit, you may NOT see that the interface changed and that your "partial" one needs to evolve. In the end, it seems you are trying to implement sme kind of adapter without the price of the adaptation – OznOg Feb 03 '19 at 18:06
  • If the functions in `partialImplementation` must be **the same** as in `interface`, `partialImplementation` should inherit `interface`. That's what inheritance is *for*. – n. m. could be an AI Feb 03 '19 at 18:40

1 Answers1

0

The option you don't want

It is not clear what you intend to do. But one thing is for sure: in your solution the fnA() of partialImplementation has nothing to do with the fnA() of interface, since both classes are unrelated. Furthermore, in partialImplementation this function is not virtual.

So to get the partialImplementation's fnA() as a virtual function in a class derived from interface, the explicit call that you have exposed is the only way to proceed.

If you want to get rid of the boilerplate code, you have to make partialImplementation inheriting from interface. It will still be an abstract class that can't be instantiated, since fnB() is still missing.

class partialImplementation : public interface { ... };

class myClass : public partialImplementation {
public:
    void fnB() const {cout << "fnB from myClass" << endl;} 
};

Want to combine several partial implementations ?

It is not clear why you don't want this inheritance. If you want to combine several different partial implementations, in a mixin stile, but you want to avoid having several distinct interface sub-objects, you could opt for virtual inheritance:

class partialImplementationA : public virtual interface { 
public: 
    void fnA() const {cout << "fnA from partial implementation A" << endl;}
};
class partialImplementationB : public virtual interface { 
public: 
    void fnB() const {cout << "fnB from partial implementation B" << endl;}
};

class myClass : public virtual interface, 
                public partialImplementationA, 
                public partialImplementationB {
public:
};

Online demo

The inconvenience, is that the inheritance has to be declared virtual at all levels. But it allows to achieve the kind of things that you want to do without the boilerplate code.

Christophe
  • 68,716
  • 7
  • 72
  • 138