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?
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.
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.
¶ Δ 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.
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.
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.
Basically your case is custom made for Template method design pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With