knowledge/technology/dev/programming/patterns/creational/RAII Pattern.md
2024-01-17 09:00:45 +01:00

57 lines
No EOL
2.7 KiB
Markdown

---
obj: concept
---
# Resource Acquisition Is Initialization (RAII)
## **Description:**
Resource Acquisition Is Initialization (RAII) is an idiom rather than a design pattern, but it's an important and widely used programming technique. RAII ties the lifetime of a resource (e.g., memory, files, locks) to the scope of an object. It ensures that the resource is automatically acquired when an object is created and automatically released when the object goes out of scope, thus preventing resource leaks and simplifying resource management.
**How it's Used:**
1. **Resource Management Class**: Create a resource management class (often referred to as a "wrapper" or "smart" class) that encapsulates the resource's allocation and deallocation logic.
2. **Constructor**: In the constructor of the resource management class, acquire the resource (e.g., allocate memory, open a file, acquire a lock).
3. **Destructor (or Dispose Method)**: In the destructor (or a dispose method for languages like C#), release the resource (e.g., deallocate memory, close a file, release a lock). The destructor is automatically called when the object goes out of scope.
4. **Use in Client Code**: In your client code, create an instance of the resource management class. The resource will be automatically acquired when the object is created and automatically released when it goes out of scope.
## **Example:**
A common example of RAII is managing dynamic memory in C++ using the `std::unique_ptr` smart pointer:
```cpp
#include <iostream>
#include <memory>
class MyResource {
public:
MyResource() {
// Acquire a resource (e.g., allocate memory)
data = new int[10];
std::cout << "Resource acquired." << std::endl;
}
~MyResource() {
// Release the resource (e.g., deallocate memory)
delete[] data;
std::cout << "Resource released." << std::endl;
}
void performOperation() {
// Perform some operation with the resource
std::cout << "Operation performed." << std::endl;
}
private:
int* data;
};
int main() {
// Create an instance of MyResource
MyResource resource;
// Use the resource
resource.performOperation();
// Resource is automatically released when 'resource' goes out of scope
return 0;
}
```
In this C++ example, the `MyResource` class acquires and releases a resource (dynamic memory) in its constructor and destructor, respectively. When you create an instance of `MyResource` in the `main` function, the resource is automatically acquired, and when `resource` goes out of scope at the end of `main`, the resource is automatically released. This ensures that you don't have to worry about explicitly managing the resource's lifecycle in your client code, reducing the risk of resource leaks.