# C++ Resource Acquisition is Initialization (RAII)
## Resource Acquisition is Initialization (RAII)
* reference: https://www.youtube.com/watch?v=T3etG2THif8&t=190
* a fundamental concept in **C++ programming** that leverages the **language's object lifecycle management features** specifically **constructors** and vdestructors** to manage resource allocation and deallocation automatically.
* This design pattern ensures that resources such as **dynamic memory**, **file handles**, **network connections**, and more are **properly released when they are no longer needed**, which helps to **avoid resource leaks** and ensures more robust code.
* In the RAII pattern, resources are **encapsulated within objects**
* benefit
* **Exception Safety**: By managing resources automatically, RAII handles resource deallocation even in the face of exceptions. This makes RAII a cornerstone of writing exception-safe code in C++.
* **Resource Leak Prevention**: By tying resource management to the lifetime of objects, RAII **ensures** that resources are not inadvertently left allocated after they are no longer needed.
* **Simplicity and Safety**: RAII can simplify code by **abstracting** the resource management tasks into the lifecycle of objects, **making the code cleaner and safer**.
* example
1. **managing a mutex in a multi-threaded application**, use RAII to ensure that a mutex is locked when needed and automatically released
```
#include <mutex>
#include <iostream>
class Lock {
std::mutex& mtx;
public:
Lock(std::mutex& m) : mtx(m) {
mtx.lock();
std::cout << "Lock acquired" << std::endl;
}
~Lock() {
mtx.unlock();
std::cout << "Lock released" << std::endl;
}
};
int main() {
std::mutex mtx;
{
Lock lock(mtx);
// Do thread-safe work here
} // Lock is automatically released when going out of scope
return 0;
}
```
2. **RAII in Standard Library**, The C++ Standard Library makes extensive use of RAII. For instance, smart pointers such as std::unique_ptr and std::shared_ptr use RAII to manage dynamic memory. When a smart pointer goes out of scope, it automatically deallocates the memory it owns, thus preventing memory leaks
```
#include <memory>
void function() {
std::unique_ptr<int> ptr(new int(10)); // Automatically deleted when function returns
// Use ptr
} // ptr goes out of scope and the memory is deallocated automatically
```
3. management dynamic memory: 假如今天想要dynamic allocate一個memory(在這裡是array),那programmer除了```new```,在程式結束前還要記得```delete```,否則會造成memory leak問題。however當project很大時,此創自出來object歸屬誰又甚麼時候要delete很難分界而且容易忘掉造成memory leak。因此如何妥善處理memory回收問題很重
* **bad implement**: 使用者直接使用new,但有可能會忘記造成memory leak
```
int main(){
arr = new int[10];
// operation
arr[0] = 7;
// forget to delete the dynamically allocated memory(arr) here!!! memory leak
return 0;
}
```
* **good implement**: 我們可以利用c++中class object在其life cycle開始及結束前會執行constructor以及destructor的特性來把要new的東西包在object中,並且使用將```new```放在constructor,而```delete```放在destructor,如此不管怎樣,此物件一定會在程式結束前被delete掉
* 這裡有一個時做細節,當我們要用class來把這些資料結構(arr,int,...)包起來時,我們也要在class method中定義原本資料結構所擁有的operator,如此才可以讓此class用起來像是原本的資料結構
* [原本資料結構中所用到operator長怎樣?](<https://en.cppreference.com/w/cpp/language/operators>)
* c++ operator overload文件定義了不同operator長怎樣,
* 進入網站中用```ctrl+f```找到對應operator符號對應資料結構的定義方式
* 然後將class(資料結構封裝)所要用到operator複製到class method中
```
// good implement
class collection{
public:
collection(){
arr = new int[10];
}
~collection(){
delete[] arr;
}
int& operator[](std::size_t idx){
return data[idx];
}
const int& operator[](std::size_t idx) const{
return data[idx];
}
private:
int* arr;
}
int main(){
collection coll1;
// operation on collection object like the normal arr
coll1[0] = 7;
coll1[1] = 2;
std::cout << coll1[0] << std::endl;
return 0;
}
```
## exception safe code
reference: