Is there a way to force the overridden method to be called?

The code script looks like this:

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 ()? Suppose the call foo()

is vital and should always be called when called doSomething()

. Of course the child class can call ParentClass::doSomething()

, but it seems a little "risky" since it doesn't apply.

I came up with a dirty solution that looks something like this:

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

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

      

Thus, child classes have to do the implementation, and they foo()

always get called, but the method is not the same. Are there any more elegant solutions?

+3


source to share


2 answers


This is not a messy solution, but a non-virtual interface idiom (or a template pattern template) that you discovered yourself.

By defining a non-virtual function that calls a virtual function (by the way), you are enforcing every implementation of your class to implement non-virtual behavior. An implementation is free to change part of this behavior, that is, a call to a virtual function.

This is usually done like this:



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
    }
};

      

Creating a virtual public and virtual private also ensures that no one can call fooImpl

on these classes, which is what you need as you need some material to be done before and / or after the call fooImpl

.

+3


source


Let's see if this work can:

class parent {
     void foo() {...}
     virtual void doFinal() {...}
     void doSomething (){foo(); doFinal();}
}

class child {
    virtual void doFinal() {...}
}

      



So you can override doFinal and use doSmthing.

0


source







All Articles