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?
|
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 |
|||||||||||||||||
|
|
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. |
|||
|
|
