wrhall
wrhall

Reputation: 1308

Is std::unique_ptr an application of RAII?

Is that an accurate description of it? Does it make sense?

Are you guaranteed that the object it points to won't be deleted until the unique_ptr goes out of scope [even if you're not using the unique_ptr]?

Upvotes: 7

Views: 4794

Answers (4)

Ben Voigt
Ben Voigt

Reputation: 283733

Yes, std::unique_ptr follows the RAII design principle.

No, std::unique_ptr does not prevent other code from doing something stupid, like calling delete on a pointer that belongs to the unique_ptr. The unique_ptr itself will call a deleter1 on the object it owns when either:

  1. it goes out of scope

or

  1. the unique_ptr is reassigned (via operator= or reset) to point to a different object

One can also revoke unique_ptr's ownership of an object by moving to a different smart pointer, or using the release member function. This breaks the association between the object and the unique_ptr and unique_ptr will no longer clean up the object.


1 The default deleter will use either delete or delete [], depending on whether the target has array type. But unique_ptr is a template and its deleter can be customized, for example the cleanup operation for a FILE* can be chosen to be a call to fclose.

This capability can be used to schedule an arbitrary cleanup action to take place when the unique_ptr goes out of scope. RAII is used for keeping locks, closing files, and so forth -- clearly there would be major problems if the cleanup action were performed early just because the compiler didn't see any future usage of the smart pointer. Luckily the C++ object lifetime rules are completely deterministic (even the order of destruction for multiple automatic variables in the same scope is well defined), and you can count on the smart pointer cleaning up its owned object exactly when the smart pointer is itself destroyed.

Upvotes: 13

Paolo M
Paolo M

Reputation: 12777

It is an application of RAII, indeed.

But you are not granted that the object it points to is not deleted by someone else before the unique_ptr goes out of scope.

E.g.

int* p = new int;
int* cp = p;
std::unique_ptr<int> up(p);
delete cp;

will give undefined behavior.

Upvotes: 2

vsoftco
vsoftco

Reputation: 56567

std::unique_ptr can be used for RAII, but doesn't prevent you from doing something like this:

#include <memory>

class Foo{};

int main()
{
    Foo* pFoo = new Foo;

    std::unique_ptr<Foo> upFoo(pFoo);
    delete pFoo; // WRONG, double deletion when upFoo's destructor is called
}

Usually, the best way to use smart pointers is to pass the raw pointer as their constructor or make-like function, such as

#include <memory>

class Foo{};

int main()
{
    std::unique_ptr<Foo> upFoo(new Foo); // or make_unique in C++14
}

Upvotes: 1

Guvante
Guvante

Reputation: 19213

std::unique_ptr is RAII, as the creation of the object also initializes it.

Are you guaranteed that the object it points to won't be deleted until the unique_ptr goes out of scope [even if you're not using the unique_ptr]?

If you make a few assumptions:

  • You don't move the unique_ptr (that would cause the newly moved to location to be the one that will delete
  • You don't delete the pointer yourself or add it to another control structure.

Or put more succinctly, yes it will live that long.

Upvotes: 2

Related Questions