0

I happened to stumble upon this post on Stack Overflow: make shared_ptr not use delete

and I have a related question from the C++ standard library book by Nicolai M. Josuttis. Below is the following piece of code from the book:

#include <string>  
#include <fstream>   // for ofstream  
#include <memory>    // for shared_ptr  
#include <cstdio>    // for remove()  

class FileDeleter
{
  private:
  std::string filename;
  public:
  FileDeleter (const std::string& fn)
  : filename(fn) {
  }
  void operator () (std::ofstream* fp) {
   delete fp;                     // close file
   std::remove(filename.c_str()); // delete file
  }
};

int main()
{
 // create and open temporary file:
 std::shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"),
                                  FileDeleter("tmpfile.txt"));
//...
}  

I understand that the signature of the deleter function should be of the following :

void Deleter(T* p)

So in the above example, how is it that the deleter function (specified as FileDeleter("tmpfile.txt")) looks to be a constructor call for the class rather than a function with the above format? How does the deleter function actually get invoked on destruction of the shared pointer here?

2
  • " How does the deleter function actually get invoked on destruction of the shared pointer here?" From within the shared_ptr's destructor?!? Commented Oct 8, 2014 at 0:01
  • @programmerjake : I know about functors. But it was still not clear to me that's why I asked the question. Commented Oct 8, 2014 at 12:08

1 Answer 1

1

FileDeleter("tmpfile.txt") creates a deleter object to pass to the shared pointer.

The shared pointer's implementation stores a copy this somewhere as a variable, as well as the managed object, along the lines of

std::ofstream * object;
FileDeleter deleter;

The shared pointer's destructor will invoke this as

deleter(object);

which will call the deleter's overloaded operator(), deleting the object and removing the file.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Mike! To be more nosy, can I assume that the deleter object FileDeleter("tmpfile.txt"), is 'copied' somewhere in the shared_ptr's implementation and it is on this object that the operator() is invoked? Does that mean that the class needs to have a public copy constructor?
@avish: It will be copied, or moved if you pass it as an rvalue (as you do here); so it does need a public copy or move constructor. In general, when the standard library wants a functor, it takes it by value and copies/moves it as required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.