Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Virtual functions that need to call the same code?

I have a base class and classes that derive from it. The base class Controllable acts as an interface for an input loop, and other classes derive from it to get a spot in that loop to get events like if a key is pressed.

class Controllable{
public:
    virtual void setActive(bool state) { m_active = state; }
    virtual void input(Event & e) =0;
private:
    bool m_active;
};

class Button : public Controllable{
public:
    void setActive(bool state){ /*do extra work*/ m_active = state; }
    void input(Event & e) override;
};

Since the Button class deals with events from an event queue, setting it to inactive (which takes it out of the input loop) may cause it to miss important events like a key being unpressed, so it needs extra code to put it into a friendly inactive state should it ever become active again later.

My question, what is the best way to ensure that setActive always has the intended effect of switching m_active to the correct state, while at the same time, not requiring derived classes to define it unless they need to attach extra needed code?

like image 941
Anne Quinn Avatar asked Jan 09 '12 18:01

Anne Quinn


People also ask

Where the virtual function should be different?

Where the virtual function should be defined? Explanation: The virtual function should be declared in base class. So that when the derived class inherits from the base class, the functions can be differentiated from the one in base class and another in derived class.

Can virtual functions be called?

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

Do virtual functions have to be overridden?

¶ Δ A pure virtual function is a function that must be overridden in a derived class and need not be defined. A virtual function is declared to be “pure” using the curious =0 syntax.


3 Answers

Keep the setActive method non-virtual and then define a separate protected method activeChanged that the child classes can override

class Controllable{
public:
    void setActive(bool state) { m_active = state; activeChanged(state); }
    virtual void input(Event & e) = 0;
protected: 
    virtual void activeChanged(bool newState) {}
private:
    bool m_active;
}

class Button : public Controllable{
protected:
    void activeChanged(bool newState){ /*do extra work*/ }
public:
    void input(Event & e);
};

With this approach you are keeping the external public interface separated from the internal protected interface intended for child classes.

like image 127
Anders Abel Avatar answered Oct 24 '22 19:10

Anders Abel


One way to do this is to define "pre" and "post" virtual methods:

class Controllable{
public:
    void setActive(bool state) {
        preSetActive(m_active, state);
        m_active = state;
        postSetActive(m_active);
    };
    virtual void input(Event & e) =0;
protected:
    virtual void preSetActive(bool oldState, bool newState) {}
    virtual void postSetActive(bool newState) {}
private:
    bool m_active;
}

Note that the setActive() method is not virtual in this technique.

like image 23
Greg Hewgill Avatar answered Oct 24 '22 19:10

Greg Hewgill


Basically your case is custom made for Template method design pattern.

like image 35
Alok Save Avatar answered Oct 24 '22 17:10

Alok Save