1

I have an class:

class MyCoolBean {

public:

    virtual void toot(){
        log("ooh la la");
    }
}

And my derived class:

class MyCoolBeansBoy : public MyCoolBean{
public:
    void toot()override{
        log("oh yeah");
    }
}

If I do:

MyCoolBeansBoy boi; boi.toot();

The output is:

oh yeah

But I want the output to be:

ooh la la
oh yeah

Now I know I can modify the derived function to be:

    void toot()override{
        MyCoolBean::toot();
        log("oh yeah");
    }

But if I do that, then anyone implementing a derived class can simply forget. Is there anyway to force MyCoolBean::toot() to be called ?

EDIT: I know this is technically possible because of this questions answers:

How to ensure that every method of a class calls some other method first?

The solution in the above link can be used to force calling a member function by all functions! My question is how to do it only for an overriden method, and call specifically the base method! :)

Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190
  • 1
    You can't and the accepted answer of the linked question does not ensure that `log` log is called. One could still write `LoggingFoo f; f.a();` which would call `a` directly without `log` being executed. – t.niese Jul 02 '20 at 10:00

1 Answers1

8

You don't.

(because it is not possible to do it reliably, the answer in your link is nice, but it only works with pointers which is quite a restriction)

Either you want the derived method to be the same as the one in the base, then you don't declare it as virtual, or...

If you want the derived classes to extend a base class methods functionality then you can use the so-called Template Method Pattern:

class MyCoolBean {    
public:   
    void toot() {             // <- not virtual !
        log("ooh la la");
        do_toot();
    }
protected:                
    virtual void do_toot() {}        // <- customization point
};

Derived class:

class MyCoolBeansBoy : public MyCoolBean{
private:
    void do_toot() override {
        log("oh yeah");
    }
};

Now

MyCoolBeansBoy x;
x.toot();

will log both messages.

This achieves what you want but with somehow inverted logic: The base class "forces" each derived class to call a method of the derived class when a method from the base is called. do_toot could be pure virtual, then the derived class cannot forget to provide an implementation.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185