눈팅하는 게임개발자 블로그
RAII(Resource Acquisition is Initialization) 본문
C++로 코딩을 함에 있어서 RAII를 지킨다함은
크게 2가지를 지키는 것이다.
1. 객체를 생성한 시점에 해당 객체에 필요한 모든 리소스가 초기화 된 상태여야 한다.
2. 객체가 스코프를 벗어나는 시점에 해당 객체가 가진 모든 리소스를 반환해야 한다.
class Foo {
public:
Foo(const std::string& name)
: name(name)
{
namePtr = new std::string();
}
~Foo() = default;
Foo(const Foo& rhs)
: name(rhs.name)
{
}
Foo& operator=(const Foo& rhs) {
name = rhs.name;
return *this;
}
private:
std::string name;
std::string* namePtr;
};
위의 코드는 RAII의 두 가지 규칙을 모두 지키고 있지 않다.
우선 첫번째로 Foo의 string을 매개변수로 받는 기본 생성자는
해당 객체가 가진 모든 리소스(name, namePtr 변수)들을 모두 초기화하고 있지만
또다른 Foo 객체를 매개변수로 받는 복사 생성자는 name 변수만 초기화하고 있고
namePtr 변수는 초기화하고 있지 않다.
이는 위의 1번째 규칙을 지키고 있지 않은 것이다.
그리고 두번째로 Foo의 string을 매개변수로 받는 기본 생성자에서 namePtr에 힙 메모리 리소스를 할당하였지만
소멸자인 ~Foo()는 default 키워드로 선언되어있다.
이 경우 Foo 객체가 생성되고, 스코프에서 벗어날 경우 Foo 객체는 사라지겠지만
namePtr에 할당된 힙 메모리 리소스는 반환되지 않고그대로 메모리에 남아있게 된다.
이는 위의 2번째 규칙을 어기는 셈이다.
이를 방지하기 위해 default 키워드로 선언되어 있는 소멸자를 수정하여
namePtr이 소유하고 있는 힙 메모리 리소스를 반환하는 코드를 추가해야 한다.
'공부한거 > Cpp' 카테고리의 다른 글
스마트 포인터와 일반 포인터의 성능 차이 (0) | 2020.11.12 |
---|---|
RVO(Return Value Optimization) (0) | 2020.09.30 |