RAII(Resource Acquisition Is Initialization)는 "자원 획득은 초기화"라는 철학을 담고 있는 C++의 리소스 관리 기법입니다.
핵심 아이디어는 리소스의 생명주기를 객체의 생명주기에 묶는 것입니다.
이 구조 덕분에, 함수 종료나 예외 발생 여부와 관계없이 객체가 범위를 벗어나면 자동으로 리소스가 해제됩니다.
C++은 가비지 컬렉터(GC)가 없기 때문에, 프로그래머가 직접 리소스를 해제해야 합니다.
하지만 다음과 같은 상황이 발생하면 문제가 됩니다.
void processFile() {
FILE* fp = fopen("data.txt", "r");
if (!fp) throw std::runtime_error("파일 열기 실패");
// 중간에 예외 발생 가능
throw std::runtime_error("처리 중 오류");
fclose(fp); // 실행되지 않을 수 있음 → 파일 누수 발생
}
📌 RAII 적용 후
#include <fstream>
void processFile() {
std::ifstream file("data.txt"); // 생성자에서 파일 열기
if (!file) throw std::runtime_error("파일 열기 실패");
// 중간에 예외 발생해도 소멸자가 자동으로 파일 닫음
}
RAII는 예외 안전성(Exception Safety)을 확보하는 가장 강력한 방법입니다.
스마트 포인터(std::unique_ptr, std::shared_ptr)는 RAII의 대표적인 구현입니다.
#include <memory>
void process() {
std::unique_ptr<int> ptr(new int(42)); // 생성자에서 메모리 획득
// ptr 사용
} // 소멸자에서 delete 자동 호출
std::lock_guard, std::unique_lockstd::ifstream, std::ofstream, 네트워크 소켓 래퍼 클래스장점
단점
RAII는 C++의 "리소스는 객체에 맡겨라"라는 철학을 가장 잘 구현한 기법입니다.
메모리뿐 아니라 파일, 네트워크, 락 등 다양한 리소스에 적용 가능하며,
특히 예외가 발생하더라도 안전하게 리소스를 정리할 수 있다는 점이 강력한 장점입니다.
💡 Tip: RAII를 잘 활용하면 try-catch 블록 안에서 직접 delete나 close를 호출하는 경우가 크게 줄어듭니다.