C++ 개발자로 지낸지 3년이 넘어갈 즈음에 알게된 패턴이네요반성합네다.... RAII
는 자원의 안전한 사용을 위해 객체가 쓰이는 스코프를 벗어나면 자원을 해제해주는 기법이에요. C++ 고유의 디자인 패턴이라고 하는데 그 이유는 초기화된 인스턴스가 스코프를 벗어나면 소멸자를 호출시켜 자원을 해제하는 C++에서만 구사할 수 있는 방식이에요. C++11에서 사용할 수 있는 스마트 포인터와 함께 자주 언급이 되요.
변수에 접근 가능한 시점에 변수 사용이 가능하다는 점을 컴파일 단계에서 정할 수 있어요. 아래 코드를 보며 이해해봐요.
class foo {
public:
init () {
/* 초기화 */
}
dispose() {
/* 정리 */
}
doAction() {
/* 뭔가 함 */
}
};
근데 위 코드는 문제가 많아요. 본격적으로 작성해봐요.
class foo {
public:
~foo() {
dispose();
}
init () {
if (이전에 초기화 했나?) return;
/* 초기화 */
}
dispose() {
if (아직 초기화조차 안되었나?) return;
if (이미 dispose 되었나?) return;
/* 정리 */
}
doAction1() {
if (이전에 초기화 안했나?) return;
/* 뭔가 함 */
}
doAction2() {
if (이전에 초기화 안했나?) return;
/* 뭔가 함 */
}
doAction3() {
if (이전에 초기화 안했나?) return;
/* 뭔가 함 */
}
};
근데 여기서 init
가 실패한 경우엔 dispose
를 해야할까요? 아니면 init
이 안됬으니까 굳이 dispose
를 호출할 필요도 없을까요?
RAII
는 단순히 생성자와 파괴자를 호출하는 문법이 아니라, 이에 대한 해답을 제공해주는 철학적인 접근을 가졌어요.
dispose
나 doAction
이 불려질 일이 없습니다. doAction은 항상 초기화가 되어있음을 가정하고 동작할 수 있어요초기화 뿐만 아니라 파괴에 대한 솔루션도 제공해요. 저는 이 부분이 참 마음에 들어요. 이를 활용해 만든 특정 메서드의 퍼포먼스를 측정하는 클래스를 만들었어요.
#pragma once
#include <iostream>
#include <chrono>
#include <limits>
class TimeChecker final
{
public:
TimeChecker(std::string processName)
{
this->start = std::chrono::system_clock::now();
this->processName = processName;
}
~TimeChecker()
{
std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;
std::cout.precision(3);
std::cout << processName << " : " << sec.count() << " sec(s)" << std::endl;
}
private:
std::string processName;
std::chrono::system_clock::time_point start;
};
해당 인스턴스를 지역변수로 선언하면 메서드를 벗어날 때 자동으로 측정 결과를 반환해요.
{
TimeChecker checker;
// 로지이ㅣ이이익
}
측정을 위해 아래처럼 번거로운 선언이 필요없죠.
{
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
// 로직을 수행해요.
//
std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;
std::cout.precision(3);
std::cout << processName << " : " << sec.count() << " sec(s)" << std::endl;
}
개발하는 과정에서 퍼포먼스 측정이 필요한 경우가 많았어요. 그 때마다 now()
니, 측정 시작 변수 초기화니 등등 작업하는 번거로움이 있어 이를 편하게 하는 방법이 없을 까 고민을 많이 했었는데 이번 공부를 통해 해소해서 기분이 좋았어요 ㅎㅎ. 당연하게 쓰던 것에서 답을 찾는다. 좋은 것을 배웠습니다.
RAII
에 대한 내용은 여기까지 다룰게요.