Effective C++ item 14: Think carefully about copying behavior in resource-managing classes.

In C++, the only code that can be guaranteed to be executed after an exception is thrown are the destructors of objects residing on the stack. Resource management therefore needs to be tied to the lifespan of suitable objects in order to gain automatic allocation and reclamation. They are acquired during initialization, when there is no chance of them being used before they are available, and released with the destruction of the same objects, which is guaranteed to take place even in case of errors. This is why Resource Acquisition Is Initialization(RAII) objects are introduced. Instead of using auto_ptr and shared_ptr, sometimes you need to create your own RAII objects. If you decide to create your own RAII objects, here are four most common rules you will follow:

  1. Prohibit copying. If copying an RAII class doesn’t make sense, you should prohibit it by making copy constructor private. (see item 6)
  2. Reference-count the underlying resource. Sometimes it’s desirable to hold on to a resource until the last object using it has been destroyed. When that’s the case, copying an RAII object should increment the count of the number of objects referring to the resource. This is how shared_ptr implement copying behavior. So RAII class can implement reference-counting copying behavior by containing a shared_ptr data member. In addition, if you don’t want to delete the resource after reference count goes to 0 which is default behavior of shared_ptr, you can provide custom “deleter” for shared_ptr so that every time reference count goes to 0, this “deleter” will be called.
  3. Copy the underlying resource. In this case, the only reason to use resource-managing class is to make sure each copy is released after you are done with it. So you should perform a deep copy of resource object.
  4. Transfer ownership of the underlying resource. Sometimes you want to only keep one RAII object refers to a raw resource, you need to transfer ownership of the underlying resource to a new instance. This kind of behavior is implemented by auto_ptr.

Reference:
“Effective C++” Third Edition by Scott Meyers.