---
# System prepended metadata

title: C++ RAII

---

# 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: 