shared_ptr and FILE for wrapping cstdio (update: also dlfcn.h) Even in the presence of &lt;fstream&gt;, there may be reason for using the &lt;cstdio&gt; file interface. I was wondering if wrapping a FILE* into a shared_ptr would be a useful construction, or if it has any dangerous pitfalls:

#include &lt;cstdio&gt;
#include &lt;memory&gt;

std::shared_ptr&lt;std::FILE&gt; make_file(const char * filename, const char * flags)
{
  std::FILE * const fp = std::fopen(filename, flags);
  return fp ? std::shared_ptr&lt;std::FILE&gt;(fp, std::fclose) : std::shared_ptr&lt;std::FILE&gt;();
}

int main()
{
  auto fp = make_file("hello.txt", "wb");
  fprintf(fp.get(), "Hello world.");
}


Update: I just realized that it is not allowed to fclose a null pointer. I modified make_file accordingly so that in the event of failure there won't be a special deleter.



Second update: I also realized that a unique_ptr might be a more suitable than shared_ptr. Here is a more general approach:

typedef std::unique_ptr&lt;std::FILE, int (*)(std::FILE *)&gt; unique_file_ptr;
typedef std::shared_ptr&lt;std::FILE&gt; shared_file_ptr;

static shared_file_ptr make_shared_file(const char * filename, const char * flags)
{
  std::FILE * const fp = std::fopen(filename, flags);
  return fp ? shared_file_ptr(fp, std::fclose) : shared_file_ptr();
}

static unique_file_ptr make_file(const char * filename, const char * flags)
{
  return unique_file_ptr(std::fopen(filename, flags), std::fclose);
}


Edit. Unlike shared_ptr, unique_ptr only invokes the deleter if the pointer is non-zero, so we can simplify the implementation of make_file.

Third Update: It is possible to construct a shared pointer from a unique pointer:

unique_file_ptr up = make_file("thefile.txt", "r");
shared_file_ptr fp(up ? std::move(up) : nullptr);  // don't forget to check




Fourth Update: A similar construction can be used for dlopen()/dlclose():

#include &lt;dlfcn.h&gt;
#include &lt;memory&gt;

typedef std::unique_ptr&lt;void,  int (*)(void *)&gt; unique_library_ptr;

static unique_library_ptr make_library(const char * filename, int flags)
{
  return unique_library_ptr(dlopen(filename, flags), dlclose);
}
I should start with the fact that I don't entirely agree with the widespread belief that "explicit is better than implicit". I think in this case, it's probably at least as good to have a class that just implicitly converts to the right type:

class file { 
    typedef FILE *ptr;

    ptr wrapped_file;
public:
    file(std::string const &amp;name, std::string const &amp;mode = std::string("r")) : 
        wrapped_file(fopen(name.c_str(), mode.c_str()))    
    { }

    operator ptr() const { return wrapped_file; }

    ~file() { if (wrapped_file) fclose(wrapped_file); }
};


I haven't tried to make this movable, but the same general idea would apply if you did. This has (among other things) the advantage that you work with a file directly as a file, rather than having the ugly (and mostly pointless) .get() wart, so code would be something like:

file f("myfile.txt", "w");

if (!f) {
   fprintf(stderr, "Unable to open file\n");
   return 0;
}

fprintf(f, "Hello world");


This has a couple of advantages. The aforementioned cleanliness is a fairly important one. Another is the fact that the user now has a fairly normal object type, so if they want to use overloading roughly like they would with an ostream, that's pretty easy as well:

file &amp;operator&lt;&lt;(file &amp;f, my_type const &amp;data) { 
    return data.write(f);
}

// ...

file f("whatever", "w");
f &lt;&lt; someObject;


In short, if the user wants to do C-style I/O, that works fine. If s/he prefers to do I/O more like iostreams use, a lot of that is pretty easy to support as well. Most of it is still just syntactic sugar though, so it generally won't impose any overhead compare to using a FILE * directly.