[Effective C++] #17 자원 관리 객체와 new 사용
Scott Meyers의 "Effective C++"를 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 해당 항목은 3장 "자원 관리", 항목 17 "new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자"에 해당하는 내용입니다.
자원 관리 객체의 메모리 동적 할당
void someFunc (std::tr1::shared_ptr<A_클래스>, int priority){
...
};
int priority = 1;
someFunc(std::tr1::shared_ptr<A_클래스>(new A_클래스), priority);
위 예제 코드는 동적으로 할당받은 A_클래스 객체에 대한 자원 관리 객체(shared_ptr)와 정수형 변수를 인자로 받는 함수를 구현합니다. 자원 관리 객체에 대한 자세한 내용은 아래 링크를 살펴보시기 바랍니다. 위 코드의 경우 컴파일은되지만, 문제가 존재합니다. 컴파일러는 someFunc 함수 호출 전 인자들을 평가하는 순서를 가집니다. 첫 번째 인자는 두 부분으로 나누어지는데, std::tr1::shared_ptr의 생성자 호출 부분과 new A_클래스를 통한 동적 할당 실행 부분입니다. 따라서 someFunc 함수가 정상적으로 실행되기 위해 컴파일러는 new A_클래스의 메모리 동적 할당, shared_ptr의 생성자 호출, 그리고 priority 변수 호출을 수행해야 합니다. 이때, "std::tr1::shared_ptr <A_클래스> (new A_클래스)"의 경우 메모리 동적 호출 연산이 선제적으로 수행되어야 합니다. 그 이유는 자원 관리 객체의 생성자 호출을 위해 우선적으로 A_클래스 객체에 대한 정보가 필요하기 때문이죠. 추가적으로, "new A_클래스"를 통해 생성한 자원이 자원 관리 객체로 넘어가는 시점에 발생하는 예외는 자원 누출의 위험 또한 내포합니다. 그 이유는 "priority" 변수의 호출 또한 순서가 정해져 있지 않아, "new A_클래스" -> "priority" -> "std::tr1::shared_ptr <A_클래스>"의 순서는 A_클래스 자원을 자원 관리 객체(shared_ptr)에게 넘기기 전에 발생하는 예외에 취약하다는 것을 의미합니다. 따라서, A_클래스를 생성해서 자원 관리 객체에게 넘기는 코드를 별도로 작성하고, 자원 관리 객체를 함수의 인자로 넘기는 방법이 더 안전합니다.
std::tr1::shared_ptr<A_클래스> ptr (new A_클래스);
int priority();
someFunc (ptr, priority());
위와 예제 코드가 자원 누출을 방지하는 더욱 효과적인 코드 작성 방법입니다.
new로 생성한 객체를 자원 관리 객체에 넘기는 코드는 별도로 작성합시다.
'언어 > Effective C++' 카테고리의 다른 글
[Effective C++] #19 클래스 설계 (0) | 2022.01.24 |
---|---|
[Effective C++] #18 인터페이스 설계 (0) | 2022.01.18 |
[Effective C++] #16 new 및 delete 사용 (0) | 2022.01.17 |
[Effective C++] #15 자원 관리 객체, 자원에 대한 접근 (0) | 2022.01.15 |
[Effective C++] #14 자원 관리 객체 심화, RAII, shared_ptr, 삭제자 지정 (0) | 2022.01.14 |