📒 C++ - RAII(resource acquisition is initialization)
📌 RAII란?
- C++에서 자주 쓰이는 Idiom으로 자원의 안전한 사용을 위해서 고안된 기법
- 스코프를 벗어나게 되면 소멸자가 호출되는 것을 이용하여 메모리를 해제해 주는 기법
#include <iostream>
using namespace std;
class Test
{
public:
~Test()
{
cout << "~Test" << endl;
}
};
void func()
{
throw "exception";
}
int main()
{
int* i = nullptr;
try
{
i = new int;
func();
delete i;
}
catch (const char* e)
{
delete i;
cout << e << endl;
}
}
- 위 코드를 보면 i를 해제하기 위해 try와 catch 모두에서 i를 해제하고 있다.
- 만약, catch가 여러 개인 상황이라고 가정한다면 모든 catch에서 i를 해제해야 하는 이슈가 생긴다.
- 이를 해결하기 위해 고안된 기법이 RAII기법이다.
#include <iostream>
using namespace std;
class RAII
{
public:
int* i;
RAII()
{
i = new int;
cout << "RAII 생성자" << endl;
}
~RAII()
{
delete i;
cout << "~RAII 소멸자" << endl;
}
};
void func()
{
throw "exception";
}
int main()
{
int* i = nullptr;
try
{
RAII raii;
func();
}
catch (const char* e)
{
cout << e << endl;
}
}
Output:
RAII 생성자
~RAII 소멸자
exception
- 소멸자에서 i를 해제시켜 줌으로써 위에서 발생했던 이슈를 해결할 수 있다.
📌 unique_ptr을 사용한 RAII
#include <iostream>
using namespace std;
class Test
{
public:
~Test()
{
cout << "~Test" << endl;
}
};
void func()
{
throw "exception";
}
int main()
{
int* i = nullptr;
try
{
unique_ptr<Test> test(new Test());
func();
}
catch (const char* e)
{
cout << e << endl;
}
}
- <Test>가 내부적으로 포인트로써 동적 할당되고, try를 벗어날 때 unique_ptr의 소멸자가 호출되면서 동적 할당을 해제한다.