Note that there are some explanatory texts on larger screens.

plurals
  1. POClean-up code in the C++ exception's destructor
    primarykey
    data
    text
    <p>Can we use the destructor of an exception as a place to put some clean-up code? </p> <p>In this manner we may allow the client to control the finalization step as opposed to RAII. Is this a good or a bad design? Is this a correct solution in the context of OOP and C++?</p> <p>I'm currently working on an asynchronous procedure which itself starts asynchronously multiple tasks. The pattern looks as follows:</p> <pre><code>struct IAsyncResult { ... virtual void EndCall() const; } typedef std::shared_ptr&lt;IAsyncResult&gt; IAsyncResultPtr; struct IAsyncTask { virtual IAsyncResultPtr BeginTask() = 0; virtual void EndTask(IAsyncResultPtr async) const = 0; } class CompositeTask : public IAsyncTask { … } </code></pre> <p>Unfortunately I’m unable to guarantee that each subtask’s BeginTask method will not fail. So it is possible that N-1 subtasks would start successfully and the Nth fail. </p> <p>In general it is vital to be sure that no background tasks are running before the client’s code finishes. But sometimes the client doesn’t care if some tasks fail.</p> <p>So my current solution involves a custom exception which is thrown from the CompositeTask’s BeginAsync method in case if one task failed to start. This allows a client to control the clean-up stage:</p> <pre><code>class composite_async_exception : public std::exception { std::vector&lt;IAsyncResultPtr&gt; successfully_started_tasks; mutable bool manage_cleanup; public: composite_async_exception(std::vector&lt;IAsyncResultPtr&gt; const&amp; _successfully_started_tasks) : successfully_started_tasks(_successfully_started_tasks) , manage_cleanup(true) { } virtual ~composite_async_exception() throw() { if(!manage_cleanup) return; for( auto task = successfully_started_tasks.begin(); task != successfully_started_tasks.end(); ++task) { task-&gt;CancelTask(); } } void Giveup() const throw() { manage_cleanup = false; } }; </code></pre> <p>And the client uses the code as shown:</p> <pre><code>try { compositeTask.BeginAsync(); } catch(composite_async_exception const&amp; ex) { //prevent the exception to cancel tasks ex.Giveup(); // some handling } </code></pre> <p>Are there some best practices to handle such a situation?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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