How to call the virtual method before calling overriden method outside the class?

101 Views Asked by At

The obvious solution is:

class GUI{
public:
    virtual void render() {
        //Common render code
    }
}

class MainGUI : public GUI {
private:
    void render() override {
        GUI::render();
        //MainGUI render code
    }
}

int main(...){
   GUI* mainGUI = new MainGUI();
   mainGUI->render();
}

Common render code will be executed before executing the MainGUI render code.

But what if I don't want to call GUI::render(); in every class that inherits GUI? And how to open the virtual method render() only to the specific method?

My first thought was to use a separate method to call Common render code and then call the virtual method:

class GUI{
public:
    void render(){
        //Common render code
        renderImpl();
    }
private:
    virtual void renderImpl() = 0;
}

class MainGUI : public GUI {
private:
    void renderImpl() override {
        //MainGUI render code
    }
}

int main(...){
   GUI* mainGUI = new MainGUI();
   mainGUI->render();
}

This code solves the first question, but not the second. I can make the non-virtual render() private, and then specify main() as a friend to open all the hidden methods and fields of the class.

But this solution could potentially lead to calling renderImpl() instead of render(). I mean the programmer's mistake.

So, how to solve this problem?

EDIT:

Sorry for confusion. I couldn't formulate the question title correctly.

My main problem was related more to friendly classes than to virtual methods. @Jarod42's comment pointed me to right solution.

1

There are 1 best solutions below

0
user10 On

Try this sort of Template method pattern where your render() method contains step (internal_render) you can override:

class GUI {
private:
    virtual void internal_render() = 0;
    void common_render() {
        std::cout << "Common render ";
    };
public:
    void render() {
        common_render();
        internal_render();
    }
};

class MainGUI : public GUI {

private:
    void internal_render() override {
        std::cout << "Derived render";
    }
};

int main() {
    GUI* mainGUI = new MainGUI();
    mainGUI->render();
}