Search code examples
c++c++11exceptionsmart-pointersraii

passing pointer ownership exception-safely


I have a situation where passing ownership of a raw pointer may throw an exception. There are several such blocks, and it would be inelegant to wrap each in a try/catch just to delete pointers which weren't accepted. Instead I'm using a unique_ptr<A> to manage my pointer with RAII:

unique_ptr<A> a(new A());
obj.take(a.get()); // pass ownership to obj, might throw
a.release(); // release pointer since obj is now responsible

So the idea behind this is to keep ownership of the raw pointer in the current function until it has been successfully passed to somebody.take(). This seems like a very nice pattern to me, but is it really? Any pitfalls I'm overlooking?


Solution

  • Alright, for anyone wondering, this is what I've done now to pass ownership of a pointer safely:

    class C {
      A *mem_p = nullptr;
    
      /** take ownership exception-safely */
      void take(unique_ptr<A> &&a) {
        dangerous_stuff(); // may throw exception    
        this->mem_p = a.release();
      }
    
      ~C() { delete mem_p; }
    }
    
    void some_fun() {
      A *ptr = new A();
      C obj;
      obj.take(unique_ptr<A>(a)); // either obj owns ptr or it is freed
    }
    

    What I like about this is that it makes the ownership semantics almost explicit, or at least it alerts any user of take() to pay attention to the lifetime of the argument.