Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Always when the term RAII is used, people are actually talking about deconstruction instead of initialisation ... I think I have a basic understanding what it might mean but I'm not quite sure. Also: is C++ the only RAII language? What about Java or C#/.NET? or is C++/CLI not RAII anymore?

share|improve this question

2 Answers 2

up vote 19 down vote accepted

Resource Acquisition Is Initialization means that objects should look after themselves as a complete package and not expect other code to tell an instance "hey by the way, you're going to be cleaned up soon - please tidy up now." It does usually mean there is something meaningful in the destructor. It also means you write a class specifically to manage resources, knowing that under certain hard-to-predict circumstances, like exceptions being thrown, you can count on destructors executing.

Say you want to write some code where you're going to change the windows cursor to a wait (hourglass, donut-of-not-working, etc) cursor, do your stuff, and then change it back. And say also that "do your stuff" might throw an exception. The RAII way of doing that would be to make a class whose ctor set the cursor to wait, whose one "real" method did whatever it was you wanted done, and whose dtor set the cursor back. Resources (in this case the cursor state) are tied to the scope of an object. When you acquire the resource you initialize an object. You can count on the object getting destructed if exceptions are thrown, and that means you can count on getting to clean up the resource.

Using RAII well means you don't need finally. Of course, it relies on deterministic destruction, which you can't have in Java. You can get a sort of deterministic destruction in C# and VB.NET with using.

share|improve this answer
3  
I think this is what you're getting at, but you might want to add that the reason why Java and C# don't support RAII is because of the garbage collector. In C++, a local object will be destroyed as soon as it goes out of scope. In Java/C# this isn't true. –  Jason Baker Dec 24 '10 at 1:19
    
Expanding on Jasons point, the reason why Java and C# cannot guarantee timely destruction is because of the possibility of reference cycles, which means it is impossible to determine a safe order to run the destructors. Reference cycles can also happen in C++, but the implications are different - the programmer becomes responsible for determining the destruction order and doing explicit deletes. That responsibility is very often packaged up in some higher-level classes destructor - e.g. a container class is responsible for ensuring all contained items are destructed. "Ownership" is key. –  Steve314 Dec 24 '10 at 5:51
1  
@Jason that's what I meant by "deterministic destruction" - a C++ programmer knows when the destructor will run. –  Kate Gregory Dec 24 '10 at 15:40
    
I know this is an old answer, but I'm still somewhat confused. I just learned of the term and some info says that acquisition should happen in the constructor. That doesn't really make sense to me and this answer seems to contradict it, but could you clarify? –  Per Johansson Feb 4 '12 at 20:47
1  
@PerJohansson Yes, you acquire in the ctor. And you release in the dtor. I was focusing on the second point, but they go together. Once the ctor is done you know you have a valid object. And you know that no matter what happens, the resource will be released at the right time. –  Kate Gregory Feb 5 '12 at 16:16

RAII is partly about deciding when an object becomes responsible for its own cleanup - the rule being that the object becomes responsible if and when its constructor initialisation completes. The symmetry of initialisation and cleanup, constructor and destructor, means the two have close ties to each other.

One point of RAII is to ensure exception safety - that the application remains self-consistent when exceptions are thrown. At first sight this is trivial - when an exception causes a scope to exit, the local variables in that scope need to be destructed.

But what happens if the exception throw occurs within a constructor?

Well, the object hasn't been fully constructed, so cannot be safely destructed. The constructor should have try blocks as needed to ensure that any necessary cleanups are done before the exception is propogated. Once the exception propogates outside the scope where the object was constructed, there will be no destructor call, because the object wasn't constructed in the first place.

Consider in particular the constructors for member data inside the object being destructed. If one of those throws an exception, your main constructor code won't run at all - but some code that forms an implicit part of that constructor will have. Any members that have been successfully constructed will be automatically destructed. Any members that were not constructed (including the one that threw the exception) aren't.

So basically, RAII is a policy that ensures that anything that gets fully constructed will get destructed in a timely way, particularly in the presence of exception throws, and that any object either gets fully constructed or it isn't (there are no half-constructed objects that you can't know how to safely clean up). Resources that are allocated are also freed. And a lot of the work is automated, so the programmer doesn't have to worry too much about it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.