I’ve been making use of callbacks to reduce coupling between some C++ classes. To define terms: I’ll call the class making the callbacks the caller, and the class receiving the callback the callee. Typically (but not necessarily), the callee will own the caller. By design, the caller has no knowledge of the callee.
I’m running into an issue relating to the lifespan of the caller object: It has no guarantee that it will still be alive after making any arbitrary callback. Take this basic example:
void caller::f()
{
/* Some work */
if (...)
{
/* [1] Execute callback */
_callee->callback(this);
}
/* [2] Some more work */
}
Say that the callee has dynamically allocated the caller, and has registered for the callback specifically to wait for a certain condition to occur. When it does, the callee will delete the caller from within the callback at [1]. If that’s the case, control will then return to caller::f, but this will have been deleted, and any code at [2] will more than likely crash.
In the general case, the caller can’t assume anything about the callee. It doesn’t know if the callee owns this, or if it might deallocate this, so I would need some general means of preventing deallocation for the scope of the caller’s member function.
I believe a possible solution revolves around boost::shared_ptrs and enable_shared_from_this, though I’ve never used it. Since these callbacks are running very frequently (40+ times per second) on mobile devices with limited processing power, I’m also worried about the overhead of creating and passing out that many shared_ptrs.
Delegation is a pretty common pattern in Objective-C. I’m far less familiar with common C++ design patterns. Is there any quick-and-easy fix for this issue? If not, how would this design typically be accomplished in C++?
Go ahead and use the shared pointer, though if possible use
std::shared_ptrinstead ofboost::shared_ptr. It’s in the (current) standard library, so no need to add an unnecessary boost dependency. If you’re already using boost, then that’s fine too.You didn’t specify what sort of mobile device you’re talking about, but the processors in modern smartphones run at hundreds or thousands of megahertz, and even low-power phones often run Java programs (with garbage collection) just fine. Shared pointers are basically reference counted. It’s not a resource-intensive activity.
If your device is able to actually run the callback more than 40 times per second, I doubt it will have any trouble with shared pointers. Don’t prematurely optimize for execution speed. DO prematurely optimize for safety and sanity.