These days in C++, if a class needs some behavior customization point, a std::function member often works well and doesn’t require additional classes or dependencies. C++ also has function templates which can be used for injecting dependencies in some situations.
As an example of using std::function, here’s a Component that paints itself using std::function :
class DrawClass : public Component
{
public:
DrawClass() {}
void paint(Graphics& g) override
{
if (DrawFunction) // check the callback function has been set
DrawFunction(g,getWidth(),getHeight());
}
std::function<void(Graphics&, int,int)> DrawFunction;
};
Then another class can use it with something like :
m_draw_a.DrawFunction = [](Graphics& g, int w, int h)
{
g.setColour(Colours::white);
g.drawLine(0, 0, w, h);
};
m_draw_b.DrawFunction = [](Graphics& g, int w, int h)
{
g.setColour(Colours::yellow);
g.fillEllipse(0, 0, w, h);
};
m_message = "Hello!";
m_draw_c.DrawFunction = [this](Graphics& g, int w, int h)
{
g.setColour(Colours::white);
g.drawText(this->m_message, 0, 0, w, h, Justification::centred);
};
So, in that case, no separate new classes are needed to draw the white diagonal line, the yellow filled ellipse or the text message. m_draw_a, m_draw_b and draw_c are all DrawClass instances, potentially reducing class dependencies. Especially the draw_c case is interesting in terms of reducing class coupling because it captures information from the current class instance (“this”) in scope. The DrawClass doesn’t need to know anything about the other class involved.