Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ memory management patterns for objects used in callback chains
    text
    copied!<p>A couple codebases I use include classes that manually call <code>new</code> and <code>delete</code> in the following pattern:</p> <pre><code>class Worker { public: void DoWork(ArgT arg, std::function&lt;void()&gt; done) { new Worker(std::move(arg), std::move(done)).Start(); } private: Worker(ArgT arg, std::function&lt;void()&gt; done) : arg_(std::move(arg)), done_(std::move(done)), latch_(2) {} // The error-prone Latch interface isn't the point of this question. :) void Start() { Async1(&lt;args&gt;, [=]() { this-&gt;Method1(); }); } void Method1() { StartParallel(&lt;args&gt;, [=]() { this-&gt;latch_.count_down(); }); StartParallel(&lt;other_args&gt;, [=]() { this-&gt;latch_.count_down(); }); latch_.then([=]() { this-&gt;Finish(); }); } void Finish() { done_(); // Note manual memory management! delete this; } ArgT arg_ std::function&lt;void()&gt; done_; Latch latch_; }; </code></pre> <p>Now, in modern C++, explicit <code>delete</code> is a code smell, as, to some extent is <code>delete this</code>. However, I think this pattern (creating an object to represent a chunk of work managed by a callback chain) is fundamentally a good, or at least not a bad, idea.</p> <p>So my question is, how should I rewrite instances of this pattern to encapsulate the memory management?</p> <p>One option that I <em>don't</em> think is a good idea is storing the <code>Worker</code> in a <code>shared_ptr</code>: fundamentally, ownership is not shared here, so the overhead of reference counting is unnecessary. Furthermore, in order to keep a copy of the <code>shared_ptr</code> alive across the callbacks, I'd need to inherit from <code>enable_shared_from_this</code>, and remember to call that <em>outside</em> the lambdas and capture the <code>shared_ptr</code> into the callbacks. If I ever wrote the simple code using <code>this</code> directly, or called <code>shared_from_this()</code> inside the callback lambda, the object could be deleted early.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload