Imagine you had a class hierarchy like the following:
class Robot
{
public:
void OnTaskCompleted() {}
private:
Task *m_pTask;
};
class Task
{
public:
virtual void DoTask() = 0;
};
class TidyUp : public Task
{
public:
void DoTask()
{
// When TidyUp task is compeleted invoke OnTaskCompleted() from here.
}
};
I need to call OnTaskCompleted() from TidyUp::DoTask(). What would be the recommended way to do that?
I’d like to avoid:
- making OnTaskCompleted() static
- passing Robot pointer to Task
The
staticroute is not feasible unless there is only oneRobotin your program, and an instance of that robot is available statically.Passing a
Robotto the task may be OK, but it might reveal too much information and prohibit task usages with objects other than robots.A third alternative would be to make an interface-like class for completion notifications, extending it in the
Robot, and calling it from the task. Unfortunately, C++ does not make it particularly easy by pushing you into the virtual inheritance territory.You could adopt a callback approach that is common in POSIX thread libraries (passing a void pointer and a function pointer that takes a void pointer), but that is not too C++-ish.
Finally, if you are using C++11, you have anonymous functions that let you address the issue very gracefully by wrapping both a function and an object on which it operates in a single closure without using an external library, such as boost.
Here is a quick example of the third approach (link to ideone):