In the previous article, we saw how std::unique_ptr helps to clean memory. Generally it calls the default deleter (C++ delete operator) in appropriate time to clean up the allocated memory. But many times default deleter is not good enough for the pointer that you are dealing with. For example, if you work with file pointer (std::FILE *), cleaning up memory does not mean to delete the pointer. You have to close the opened file. Forgetting to close a file is a very common programming mistake in C++. Default deleter can not close a file. Here you have to use your own custom deleter that will perform your custom operation like closing the file.
How to Provide Custom Deleter to std::pointer?
The std::unique_ptr constructor takes two arguments, 1) the pointer that it owns and manages, 2) optionally a deleter which is a function pointer or std::func object. If you don’t specify the second argument, it will use C++ delete operator as default deleter. You can specify your own function as deleter.
// File Name: test.cpp // To compile: g++ test.cpp -std=c++11 #include <iostream> #include <fstream> #include <memory> void close_file(std::FILE* fp) { std::cout << "Closing file..." << std::endl; std::fclose(fp); } int main() { std::ofstream("myfile.txt") << "qnaplus.com"; std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("myfile.txt", "r"), &close_file); char str[16]; if(fp) { std::cout << std::fgets(str, 16, fp.get()) << std::endl; } return 0; }
Here, in time of creating the std::unique_ptr we provided a file pointer, fp, and our custom deleter function close_file(). When the std::unique_ptr will go out of context, the close_file() function will get called that will close the file. As we specified a custom deleter, default delete would not get called.
Lamda Function as Deleter
We can use a lamda function as deleter also. The same solution can be written as follows. This program and the above are basically same.
#include <iostream> #include <fstream> #include <memory> int main() { std::ofstream("myfile.txt") << "qnaplus.com"; std::unique_ptr<std::FILE, std::function<void(std::FILE *)>> fp(std::fopen("myfile.txt", "r"), [](std::FILE *f){ std::cout << "Closing file..." << std::endl; std::fclose(f); }); char str[16]; if(fp) { std::cout << std::fgets(str, 16, fp.get()) << std::endl; } return 0; }
The post Custom Deleter in std::unique_ptr appeared first on QnA Plus.