Search code examples
c++inheritancemethodsvirtual

Is there a way to force-invoke the overridden method?


The code scenario is as follows:

class ParentClass {
    void foo();
    virtual void doSomething() { foo(); }
};

class ChildClass : public ParentClass {
    virtual void doSomething();
};

Now, is there a way to force the child class to call the parent class' doSomething()? Let's assume that calling foo() is vital and should always be called when doSomething() is called. The child class can of course call ParentClass::doSomething(), but it seems a bit "risky" as it is not enforced.

I have come up with a "dirty" solution which is something like this:

class ParentClass {
    void foo();
    void doSomething() final {foo(); doSomethingChild(); }
    virtual void doSomethingChild() = 0;
};

class ChildClass : public ParentClass {
    virtual void doSomethingChild();
};

This way, child classes have to do the implementation and foo() is always called, but the method is not the same anymore. Is there any solutions that are more elegant?


Solution

  • This is not a dirty solution, but the non-virtual interface idiom (or template method pattern) that you discovered by yourself.

    By defining a non-virtual function that calls a virtual function (among other things), you force every implementation of your class to implement the behavior of the non-virtual. The implementation are only free to modify part of this behavior, that is, the call to the virtual function.

    This is usually done like so:

    class Base {
    public:
        void foo() {
            //do stuff
            fooImpl();
            //do other stuff
        }
    private:
        virtual void fooImpl(); //pure or not
    };
    
    class Derived : public Base {
    private:
        virtual void fooImpl(){
        // Implement or change fooImpl behavior
        }
    };
    

    Making the non virtual public and the virtual private ensures as well that nobody can call fooImpl on these classes, which is what you want as you need some stuff to be perfom before and/or after the call to fooImpl.