Resource Acquisition Is Initialization, often referred to by the acronym RAII, is a popular design pattern in many object oriented languages like C++, D and Ada. The technique, invented by Bjarne Stroustrupcite book title = The Design and Evolution of C++ last = Stroustrup first = Bjarne authorlink = Bjarne Stroustrup year = 1994 publisher = Addison-Wesley id = ISBN 0-201-54330-3] , associates acquisition of resources with the initialization of objects that release the resources upon destruction.
RAII involves assigning ownership of a resource to scoped objects for resource managementcite paper title = Exception Safety: Concepts and Techniques author = Bjarne Stroustrup url = http://www.research.att.com/~bs/except.pdf date = April 2001 format = PDF accessdate = 2007-09-02 ] . The acquisition is typically bound to the construction (initialization) and the automatic, deterministic destruction (uninitialization) is used to guarantee the resource is released. Since scoped objects are cleaned up regardless of whether the scope exits through normal use or through an exception, RAII is a key concept for writing exception-safe code [cite book last = Sutter first = Herb authorlink = Herb Sutter year = 1999 title = Exceptional C++ publisher = Addison-Wesley id = ISBN 0-201-61562-2] .
RAII is widely used to ensure exception safety. RAII makes it possible to avoid resource leaks without extensive use of exception handling blocks to release resources before permitting exceptions to propagate.
Language Support
C++ and D allow objects to be allocated on the stack, so the language scoping mechanism ensures that destructors are called when a local object's scope ends. By putting the resource release logic in the destructor, C++'s and D's scoping provide direct support for RAII.
Typical uses
The RAII technique is often used for controlling thread locks in multi-threaded applications. In that use, the object releases the lock, if held, when destroyed. Another typical example is file management, wherein the file class closes the associated file, if open, when destroyed.
The ownership of dynamically allocated memory (such as memoryallocated with new in C++ code) can be controlled withRAII, such that the memory is released when the RAII object isdestroyed. For this purpose, the C++ Standard Library defines. Furthermore, lifetime of sharedobjects can be managed by a smart pointer with shared-ownershipsemantics such as boost::shared_ptr, defined in C++by Boost and marked for inclusion in the new C++0x standard, or by policy based smart pointers such as Loki::SmartPtr from Loki.
Mutability (C++)
In C++, an important consideration of classes that implement RAII is their mutabilitycite book last = Wilson first = Matthew authorlink = Matthew Wilson year = 2004 title = Imperfect C++ publisher = Addison-Wesley id = ISBN 0-321-22877-4] . A class exhibiting "mutable RAII" provides facilitiesfor instances to be assigned a new resource; one that exhibits"immutable RAII" does not. An example of the former is; examples of the latter are the STLSoft library's stlsoft::scoped_handle and Boost.SmartPtr's boost::scoped_ptr.
Classes exhibiting "immutable RAII" are considerably easier to implement in C++, since the design need not account for assignment (including copy-assignment), except to explicitly prohibit it. Consider the following RAII class template that illustrates the simplicity of implementing "immutable RAII". Compare this with the implementation of or another "mutable RAII" smart pointer, which will have many more member functions and logic to handle premature release in cases of self-assignment.
// prevent copying and assignment; not implemented file (const file &); file & operator= (const file &);};
Class file can then be used as follows:void example_usage(){ file logfile("logfile.txt"); // open file (acquire resource) logfile.write("hello logfile!"); // continue using logfile ... // throw exceptions or return without worrying about closing the log; // it is closed automatically when logfile goes out of scope}
This works because the class file encapsulates the management of the FILE* file handle. When objects file are local to a function, C++ guarantees that they are destroyed at the end of the enclosing scope (the function in the example), and the file destructor releases the file by calling std::fclose(file_). Furthermore, file instances guarantee that a file is available by throwing an exception if the file could not be opened when creating the object.
Local variables easily manage multiple resources within a single function: They are destroyed in the reverse order of their construction, and an object is only destroyed if fully constructed. That is, if no exception propagates from its constructor.
Using RAII-enabled resources simplifies and reduces overall code size and helps ensure program correctness.
Resource management without RAII
In Java, objects are not values and must be accessed through references; hence you cannot have automatic variables of objects that "go out of scope." Instead, all objects are dynamically allocated and have indefinite lifetimes, given Java's use of garbage collection which reclaims objects at indeterminate times, if at all. Resources must thus be closed manually by the programmer. The preceding example would be written like this:
void java_example() { // open file (acquire resource) final LogFile logfile = new LogFile("logfile.txt");
try { logfile.write("hello logfile!");
// continue using logfile ... // throw exceptions or return without worrying about closing the log; // it is closed automatically when exiting this block } finally { // explicitly release the resource logfile.close();
The burden of releasing resources falls on the programmer each time a resource is used.
Ruby and Smalltalk do not support RAII, but have a simpler and more flexible pattern that makes use of methods that pass resources to closure blocks. Here is an example in Ruby:
File.open("logfile.txt", "w+") do |logfile logfile.write("hello logfile!")endThe open method ensures that the file handle is closed without special precautions by the code writing to the file. This is similar to Common Lisp's [http://www.lispworks.com/documentation/HyperSpec/Body/s_unwind.htm 'unwind-protect'] -based macros.
Python's [http://www.python.org/dev/peps/pep-0343/ 'with' statement] and the in C# and Visual Basic 2005 provide deterministic resource management within a block and do away with the requirement for explicit finally-based cleanup and release.
Perl manages object lifetime by reference counting, making it possible to use RAII in a limited form. Objects that are no longer referenced are immediately released, so a destructor can release the resource at that time. However, object lifetime isn't necessarily bound to any lexical scope. One can store a reference to an object in a global variable, for example, thus keeping the object (and resource) alive indeterminately long. This makes it possible to accidentally leak resources that should have been released at the end of some scope.
C requires significant administrative code since it doesn't support exceptions, try-finally blocks or RAII of any kind. A typical approach is to separate releasing of resources at the end of the function and jump there with gotos in the case of error. This way the cleanup code need not be duplicated.
int c_example() { int retval = 0; // return value 0 is success FILE *f = fopen("logfile.txt", "w+"); if (!f) { retval = -1; goto bailout1; } if (fputs("hello logfile!", f) = EOF) { retval = -2; goto bailout2; }
// continue using the file resource
// Releasing resources (in reverse order) bailout2: if (EOF = fclose(f)) { retval = -3; }
bailout1: return retval;}
Variations exist, but the example illustrates the general approach.
References
External links
*Article " [http://www.hackcraft.net/raii/ The RAII Programming Idiom] " by Wikipedia editor Jon Hanna (Talliesin) *Wiki [http://c2.com/cgi/wiki?ResourceAcquisitionIsInitialization "Resource Acquisition Is Initialization"] from the Portland Pattern Repository *Sample Chapter " [http://www.informit.com/articles/article.aspx?p=30642&seqNum=8 Gotcha #67: Failure to Employ Resource Acquisition Is Initialization] " by Stephen Dewhurst *Interview " [http://artima.com/intv/modern3.html A Conversation with Bjarne Stroustrup] " by Bill Venners *Article " [http://artima.com/cppsource/bigtwo3.html The Law of The Big Two] " by Bjorn Karlsson and Matthew Wilson *Blog Entry " [http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html RAII in C++] " by Jonathan Dodds *Article " [http://gethelp.devx.com/techtips/cpp_pro/10min/2001/november/10min1101.asp Implementing the 'Resource Acquisition is Initialization' Idiom] " by Danny Kalev *Article " [http://sourceforge.net/docman/display_doc.php?docid=8673&group_id=9028 RAII] " by Mike Nordell *Article " [http://www.codeproject.com/KB/cpp/RAIIFactory.aspx RAII, Dynamic Objects, and Factories in C++] " by Roland Pibinger *Article " [http://www.ddj.com/184409895 Managing Dynamic Objects in C++] " by Tom Cargill *Blog " [http://tombarta.wordpress.com/tag/raii/ tombarta RAII] " *Blog Entry " [http://waelchatila.com/2005/10/06/1128588184677.html RAII C++ Anti-Pattern] " *Article " [http://www.onlamp.com/pub/a/onlamp/2006/05/04/smart-pointers.html Smart pointers in C++] " by Julio M. Merino Vidal *Blog Entry " [http://beautifulcode.oreillynet.com/2008/04/resource_management_a_critical.php Resource Management: A Critical Look at RAII] " by Michael Feathers
Resource Acquisition Is Initialization — Ressourcenbelegung ist Initialisierung, meist abgekürzt durch RAII, für engl. resource acquisition is initialization, bezeichnet eine in der Programmiersprache C++ verbreitete Programmiertechnik, die die Steuerung der Belegung und Freigabe von… … Deutsch Wikipedia
Идиома Resource Acquisition Is Initialization — Получение ресурса есть инициализация (англ. Resource Acquisition Is Initialization (RAII)) шаблон проектирования объектно ориентированного программирования, смысл которого заключается в том, что получение некоторого ресурса совмещается с… … Википедия
Manual memory management — In computer science, manual memory management refers to the usage of manual instructions by the programmer to identify and deallocate unused objects, or garbage. Up until the mid 1990s, the majority of programming languages used in industry… … Wikipedia
STLSoft C++ Libraries — infobox software name = STLSoft C++ Libraries caption = latest release version = 1.9.57 latest release date = release date|2008|10|10 programming language = C/C++ operating system = MS Windows, Unix, partially Cross platform genre = STL extension … Wikipedia
Шаблон проектирования — У этого термина существуют и другие значения, см. Паттерн. В разработке программного обеспечения, шаблон проектирования или паттерн (англ. design pattern) повторимая архитектурная конструкция, представляющая собой решение проблемы… … Википедия
Destructor (computer programming) — In object oriented programming, a destructor (sometimes shortened to dtor) is a method which is automatically invoked when the object is destroyed. Its main purpose is to clean up and to free the resources (which includes closing database… … Wikipedia
Comparison of Java and C++ — Programming language comparisons General comparison Basic syntax Basic instructions Arrays Associative arrays String operations … Wikipedia
Memory leak — A memory leak, in computer science (or leakage, in this context), occurs when a computer program consumes memory but is unable to release it back to the operating system. In object oriented programming, a memory leak happens when an object is… … Wikipedia
Exception handling syntax — varies between programming languages to accommodate their overall syntax. Some languages don t call the concept exception handling or they may not have direct facilities for it, but they can still provide means for implementing it. Catalogue of… … Wikipedia
Ressourcenbelegung ist Initialisierung — Ressourcenbelegung ist Initialisierung, meist abgekürzt durch RAII, für englisch resource acquisition is initialization, bezeichnet eine in bestimmten Programmiersprachen (wie z. B. C++) verbreitete Programmiertechnik. Dabei wird die Steuerung… … Deutsch Wikipedia