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?

Community
  • 1
  • 1
avish
  • 61
  • 1
  • 8
  • _" How does the deleter function actually get invoked on destruction of the shared pointer here?"_ From within the `shared_ptr`'s destructor?!? – πάντα ῥεῖ Oct 08 '14 at 00:01
  • @programmerjake : I know about functors. But it was still not clear to me that's why I asked the question. – avish Oct 08 '14 at 12:08

1 Answers1

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.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 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 Oct 08 '14 at 12:14
  • @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. – Mike Seymour Oct 08 '14 at 15:52