About the only reason I can see is that it would let you state you are done()
, then do more work (say, cleanup) that you don't want your consumer to have to wait on.
Now, they could have done this:
private: void agent::do_run() {
run();
if (status() != agent_done)
done();
}
then have their framework call do_run()
instead of run()
directly (or the equivalent).
However, you'll note that you yourself can do this.
class myagent: public agent {
protected:
virtual void run() final override { /* see do_run above, except call do_run in it */ }
virtual void do_run() = 0;
};
and poof, if your do_run()
fails to call done()
, the wrapping function does it for you. If this second virtual function overhead is too high for you:
template<typename T>
class myagent: public agent {
private:
void call_do_run()
{
static_cast<T*>(this)->do_run();
}
protected:
virtual void run() final override { /* see do_run above, but call_do_run() */ }
};
the CRTP that lets you do compile-time dispatch. Use:
class foo: public myagent<foo>
{
public:
void do_run() { /* code */ }
};
... /shrug