거창하지 않지만 중요한 개발 잡담

Still Alive - RAII에 대하여

NAEU 2025. 7. 21. 16:44

"Resource Acquisition Is Initialization"
번역하자면,
"객체와 자원의 라이프 사이클을 일치시킨다"
의 의미를 가지고 있는 원칙이다

이 원칙의 핵심은 프로그래머가 직접 자원을 관리하는 것이 아닌, 생성, 파괴 및 관리의 모든 것을 객체가 하도록 만드는 것이다


왜 그래야하지?


이유는 간단하다.

프로젝트가 커지고 여러 데이터들이 생명주기를 직접 관리해야한다면 인간인 이상 놓치는 부분이 생기기 때문이다
또한 놓치지 않더라도 이 데이터를 누가 참조하는 지에 대한 것도 불명확하기에 이를 방지하고자 지향해야한다

class Player
{
   public:
      Player()
      {
         m_inventory = new Inventory;
      }
      ~Player();
      {
         delete m_inventory;
         m_inventory = nullptr;
      }
   private:
      Inventory* m_inventory;
}

그렇다면 위의 코드는 RAII를 준수하였을까?
내부 변수로 Inventory를 동적할당하여 사용하고, Player가 삭제될 때도 함께 delete하였으니 준수했다고 볼 수 있다

 

하지만 모던 C++에서는 이를 스마트 포인터를 이용하여 관리하는 것을 권장한다


여기엔 몇가지 이유가 있는데

  • 예외 안전성: 생성 도중 예외가 발생하더라도 메모리 누수를 방지
  • 대입 연산자/복사 생성자 등에서의 안정성: Rule of Five 대응
  • 자원 관리의 명시성과 추론 용이성: 코드의 의도가 명확해짐
    정도이다

포인트는 개발자가 관리에 대한 책임을 갖지 않으면 그냥 잊어먹어도 괜찮다는 원칙이다

따라서 모던 C++에서는 스마트 포인터를 활용하여 RAII를 자동화하고 안전성을 높이는 방식이 바람직하다