With shared_ptr you can use a custom deleter, like:
auto fp = shared_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
fprintf( fp.get(), "hello\n" );
and this will remember to fclose
the file regardless of how the function exits.
However, it seems a bit overkill to refcount a local variable, so I want to use unique_ptr
:
auto fp = unique_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
however, that does not compile.
Is this a defect? Is there a simple workaround? Im I missing something trivial?
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.
Why can I not pass a unique_ptr into a function? You cannot do that because unique_ptr has a move constructor but not a copy constructor. According to the standard, when a move constructor is defined but a copy constructor is not defined, the copy constructor is deleted.
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.
An unique_ptr has exclusive ownership of the object it points to and will destroy the object when the pointer goes out of scope. A unique_ptr explicitly prevents copying of its contained pointer. Instead, the std::move function has to be used to transfer ownership of the contained pointer to another unique_ptr .
Should be
unique_ptr<FILE, int(*)(FILE*)>(fopen("file.txt", "rt"), &fclose);
since http://en.cppreference.com/w/cpp/memory/unique_ptr
or, since you use C++11, you can use decltype
std::unique_ptr<FILE, decltype(&fclose)>
The above answer while its intent is OK and in practice compiles and works is wrong, because it is not specified that you are allowed to take the address of a standard library function. A C++ library implementation is allowed to provide different overloads or more parameters (with default arguments). Only calling the library function is sanctioned by the standard. Therefore, you need to wrap the call to fclose in your own function implementation or lambda, such as
unique_ptr<FILE, int(*)(FILE*)>(fopen("file.txt", "rt"),
[](FILE *fp)->int{ if(fp) return ::fclose(fp); return EOF;});
or wait for unique_resource
of https://wg21.link/p0052 to become standardized, but even there you need to use the lambda or a deleter function (object), see the more recent versions of p0052.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With