Concept
RAII ties the lifecycle of a resource (such as memory, file handles, or network connections) to the lifetime of an object. When the object is created, it acquires the resource, and when the object is destroyed, it releases the resource. This ensures that resources are properly managed and released, preventing resource leaks.
Common Use Cases
C++ Syntaxes and Examples
#include <memory>
#include <iostream>
void useResource() {
std::unique_ptr<int> ptr(new int(10)); // Acquires resource
std::cout << "Value: " << *ptr << std::endl;
// Resource is automatically released when ptr goes out of scope
}
int main() {
useResource();
return 0;
}
In this example, std::unique_ptr manages the dynamically allocated memory. When ptr goes out of scope, the memory is automatically released.
#include <fstream>
#include <iostream>
class FileHandler {
public:
FileHandler(const std::string& filename) : file(filename) {
if (!file.is_open()) {
throw std::runtime_error("Failed to open file");
}
}
~FileHandler() {
file.close(); // Ensures file is closed when object is destroyed
}
void write(const std::string& data) {
file << data;
}
private:
std::ofstream file;
};
int main() {
try {
FileHandler fh("example.txt");
fh.write("Hello, RAII!");
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Here, FileHandler ensures that the file is properly closed when the object goes out of scope, preventing resource leaks.
#include <mutex>
#include <thread>
#include <iostream>
std::mutex mtx;
void printMessage(const std::string& message) {
std::lock_guard<std::mutex> lock(mtx); // Acquires mutex
std::cout << message << std::endl;
// Mutex is automatically released when lock goes out of scope
}
int main() {
std::thread t1(printMessage, "Hello from thread 1");
std::thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
In this example, std::lock_guard ensures that the mutex is properly released when the lock object goes out of scope, preventing deadlocks.
std::unique_ptr, std::shared_ptr, and std::weak_ptr are commonly used to manage dynamic memory.