No, there is no standard template.
My advice is to avoid the novelty of the OO design trap by trying to find a single, common “base class” interface for everything. Your Dragon is very different from your Master, and it doesn’t work, trying to combine two interfaces, except for nice code abstractions. Remember that inheritance is not a code reuse tool.
The simplest approach is for each object to maintain its own internal state (as you already described), and you can draw this state. In this case, the old school switch instruction may be more understandable than using polymorphism for the same effect. Example:
class Dragon { enum State { asleep, flying, breathing_fire }; public: void draw () { switch (cur_state){ case asleep: draw_asleep (); case flying: draw_flying (); case breathing_fire: draw_breathing_fire(); } } private: void draw_asleep (); void draw_flying (); void draw_breathing_fire(); };
Experienced C ++ developers will sigh over the above code (as it should be), because the switch statement almost exactly performs a call to the polymorphic method - dispatching runtime. (Or even more mysterious: the table of method addresses.) My personal opinion is that for this particular type of class, that is, one open interface encapsulating a state machine, the switch statement is more understandable and easy to maintain, since it makes the state machine jump obviously. I think it is also clear that I understand that this is generally a bad design in C ++.
The friction of this design is caused by the dividing line between the state machine and the only open interface. A sleeping dragon is clearly not the same as a flying dragon. In fact, it will be almost nothing in common. But a higher-level design says the two are the same dragon. What a mess! Do you create different Dragon objects for each state? No, because that would bring the concept of state to the caller. Do you create different internal helper objects for each state and submit them? Perhaps, but it is quickly becoming erratic. This approach is a compromise between the two. Think of the statement as a switch to isolate ugliness. The open interface is clean, as is the private interface. Only the switch statement contains messy mess. Consider this approach, and consider other suggestions.
Finally, to draw your Master and your Dragon, a simple template or shell functor is enough:
struct Draw { template <class S> void operator()(S& s) { s.draw (); } };
The fact is that you do not need to combine two different classes just because they support the same logical operation.