2

I understand the concept of RAII: Use the destructor as a means to free resources, such as memory, or closing file handles/database connections. Coming from a Java background this was actually rather easy to understand because of the similarities to finally.

However, I do not quite understand when you actually should apply it. Obviously it should be implemented when initializing objects on the heap, but what are the other scenarios a normal programmer would have to use it for? Looking at this thread I found out that for example std::ifstream already has RAII implemented to handle the freeing of its file handle. So wrapping it in another object just to call ifstreamObj.close() in its destructor would be a waste of time. But I am pretty sure that this is not a general rule that applies to all of the libraries out there.

So my question is: when should I actually use RAII? Is there a general rule of thumb, a best-practice, or do I have to crawl through each and every class's documentation if I want to be sure? Or can I be certain that every class that implements a close()/free()/delete() (or something similar) method also takes care of calling it properly when necessary?

KUSH42
  • 131

2 Answers2

7

when should I actually use RAII?

When you acquire any resource in the member functions of your class and haven't delegated the responsibility to release those resources to another object/function, you need to make sure that you release those resources in the destructor.

If your class acquires a file handle by using std::ifstream::open(), you shouldn't have to explicitly call std::ifstream::close() since the destructor of std::ifstream will take care of it, i.e. the responsibility has been delegated to another object.

However, if your class acquires a file handle by using fopen(), you will have to make sure that destructor of your class calls fclose() appropriately.

Is there a general rule of thumb, a best-practice, or do I have to crawl through each and every class's documentation if I want to be sure?

As a rule of thump, you should assume that each class that you use, whether they are from the standard library, a vendor's library, or in-house library, adheres to the principle. If it doesn't, it's a defect and must be fixed by the party responsible for it.

You shouldn't have to call std::ifstream::close(). If the file doesn't get closed, you should inform the vendor that they need to fix the problem. In the mean time, you should write a wrapper class that takes care of the problem and use the wrapper class in rest of your code.

R Sahu
  • 2,016
1

RAII is about automatic release of acquired resources in destructor - there is a run-time guarantee that destructor will be called before object instance is going away regardless of specific mechanism being used.

So it should be used always. At the same time when object is going away its members are going away too and each will have its destructor executed on the way out. So if these member objects are implemented correctly there is no need to do anything.

A very popular idiom is to create a holder object on the stack so resources will be freed when the scope is exited (including exception being thrown)

zzz777
  • 456