Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does std::unique_ptr<A> need a special deleter if A has a destructor?

If the class A in unique_ptr<A> it's own destructor, is it necessary to declare a deleter to ensure that the unique pointer uses that destructor? The example I am thinking of is that A has a member mx of type user_matrix (a name I just made up) which needs to call a function free(...) to release its memory, one would define

~A(){ user_matrix::free(mx); /*etc*/}

Since default_deleter<> will call delete, it is my understanding that that should use ~A(). However, the example with the opening and closing of directories in Section 5.2, under "Deleters for Associated resources", of the book of Josuttis (The C++ Standard Library: A Tutorial and Reference) suggests one may need to declare a special deleter to do this, so I am confused.... Is this because, in the given example, the class DIR doesn't have a destructor that uses closedir(...)?

like image 957
Plamen Avatar asked Jul 24 '13 07:07

Plamen


People also ask

Do you need to delete unique_ptr?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.

Does unique_ptr call destructor?

Yes. Well the unique ptr has a function object that by default invokes delete on the pointed to object, which calls the destructor. You can change the type of that default deleter to do almost anything.

When should we use unique_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.

What happens when you move a unique_ptr?

A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.


1 Answers

The default deleter of std::unique_ptr<T> will call delete and the default deleter of std::unique_ptr<T[]> will call delete[] and those will call the destructors of the objects appropriately.

What may happen is that an operation need be scheduled right before the destruction, either because the destructor is incomplete (or lacking) or because you would like to do something more (for example, some logging). In this case you need a dedicated deleter to achieve this.

Suppose, for example, that you are given a handle, such as FILE* (common in C). Those handles often come with a close method of some sort and no destructor (because there is none in C).

struct FileCloser {
    void operator()(FILE* f) { if (f) { fclose(f); } }
};

UniqueFile = std::unique_ptr<FILE, FileCloser>;
like image 164
Matthieu M. Avatar answered Sep 20 '22 11:09

Matthieu M.