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

1

7

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(...)?

Palaeography answered 24/7, 2013 at 7:21 Comment(4)
The delete call that std::unique_ptr does will call the destructor.Disprize
Just remember: delete when you newed, delete[] when you new[]ed. Do similarly for other kinds of resources.Bessiebessy
Might be related: #7876264Alewife
One case where you need a special deleter is for APIs that give you a pointer to some resource, and the require that you release the resources through another function call.Patron
E
15

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>;
Eggcup answered 24/7, 2013 at 7:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.