C++ RAII design mechanism

What is RAII Design Mechanism

RAII is Resource Acquisition Is Initialization, which is the abbreviation of "Resource Acquisition Is Initialization". It is a idiomatic way of managing resources and avoiding leaks in C++ language. It is the rule that the object constructed by C++ will call its internal destructor when it leaves the scope. The approach of RAII is to use an object, obtain the corresponding resource (new) when it is constructed, control the access to the resource during the life of the object, so that it is always valid, and finally release the resource obtained during the construction when the object is destroyed (delete).

In fact, many people (including me) have been writing this way for a long time, but later discovered that this method has been abstracted into a design mechanism, so I will summarize it a little today.

When we need an object, we usually open up a piece of memory on the heap, that is, create a new object, and release the memory after use, that is, call the delete function. Then there will be a problem: if in a piece of business code, resources need to be created frequently, then if you forget to release the resource at any time, it will cause a memory leak. This greatly increases the robustness and maintainability of a piece of code. The RAII mechanism introduced below can help programmers get out of the bitter sea of ​​reminding themselves to release resources.

How to use RAII

Code that does not use the RAII mechanism

Creating and releasing resources requires a pair of operations. Before leaving the scope of the object, you must release the resource. If you forget, it will cause a memory leak. For example, the following code does not use the RAII mechanism:

#include <iostream> 
using namespace std;

int main() {
    
    
	// 申请内存
    int* array = new int[10];

    for (int i = 0; i < 10; ++i) {
    
    
		*(array + i) = i;
	}
	for (int i = 0; i < 10; ++i) {
    
    
		cout << array[i]<<" ";
	}
	cout << endl;
	
	// 显式地释放内存
    delete[] array;
    array = nullptr;
    return 0;
}

Code using the RAII mechanism

When the local variable leaves the scope, the destructor will be called, and the destructor will automatically call delete to release the resource, so the external does not need to call delete again to release the resource. So we will encapsulate the resource into a class, the constructor of the class applies for memory, and the destructor releases the memory, corresponding to the code that did not use the RAII mechanism before:

#include <iostream> 
using namespace std;

class Array {
    
    
  public:
	Array() {
    
    
		m_Array = new int[10];
		cout << "调用构造函数" << endl;
	}

	void InitArray() {
    
    
		for (int i = 0; i < 10; ++i) {
    
    
			*(m_Array + i) = i;
		}
	}

	void ShowArray() {
    
    
		for (int i = 0; i < 10; ++i) {
    
    
			cout << m_Array[i]<<" ";
		}
		cout << endl;
	}

	~Array() {
    
    
		cout << "调用析构函数" << endl;
		if (m_Array != nullptr) {
    
    
			delete[] m_Array;  
			m_Array = nullptr;
		}
	}

  private:
	int* m_Array;
};

int main() {
    
    
	// 不再需要显式地调用 delete,当 main 函数执行完成,
	// array 离开了作用域,自然就会调用析构函数释放内存
	Array array;
	array.InitArray();
	array.ShowArray();
	return 0;
}

Execute this program, the terminal prints:

调用构造函数
0,1,2,3,4,5,6,7,8,9
调用析构函数

Guess you like

Origin blog.csdn.net/weixin_41670608/article/details/126615947