일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프로그래머스
- 정렬
- 약참조
- 람다
- 알고리즘
- UE4 커스텀로그
- 언리얼가비지컬렉터
- 선택정렬
- UELOG
- stl
- 데이터애셋
- 언리얼엔진구조체
- UML관련
- 애셋로드
- 강참조
- 스마트포인터
- 크리티컬섹션
- enumasByue
- unorder_map
- map
- 정렬알고리즘
- dataasset
- 델리게이트
- 람다사용정렬
- BFS
- 자료구조
- C++최적화
- UE_LOG
- C++
- moreeffectiveC++
- Today
- Total
기억을 위한 기록들
[CPP-effective] 3-1 자원 관리에는 객체가 그만! 본문
캐릭터의 정보가 있는 캐릭터 클래스가 있고 객체를 사용자가 얻어내는 용도로 팩토리 함수만을 쓰도록 만들어져 있다고 가정해봅시다.
class Character{
//...
Character* CreateCharacter();
//...
};
함수를 통해 얻어낸 객체를 사용할 일이 없어질때, 해당 객체를 삭제해야 할 쪽은 이 함수의 호출장비니다.
아래 임시 함수에서 그렇게 만들었다고 합시다.
void DoSomething()
{
//...
Character* newCharacter= Character::CreateCharacter();
//..
delete newCharacter;
}
문제가 없어보이지만, 중간의 주석 부분에서 중간 return이나 예외처리 등 delete까지 닿지 않게되면 메모리누수(memory leak)이 발생하는등 문제가 생깁니다.
물론, 혼자서 하나하나 따져가면서 꼼꼼하게 하면 이런 문제는 생기지 않을수가 있습니다. 그런데 오랜 시간동안 혼자가 아닌 여러명의 프로그래머가 유지보수를 하며, 해당 코드가 길어지게 되면 파악하지 못하게 되고 문제가 생길 수도 있다는 점입니다. 항상 delete로 가줄거라고 믿지마시길 바랍니다. 오래가지 못할겁니다.
(책에서는 auto_ptr과 tr1의 shared_ptr으로 나와 있으나, C++11에서 auto_ptr의 단점이 있어, 사라지고 unique_ptr이 생겼다.)
결국에는 항상 해제 되도록 해주어야 하는데 이것이 바로 스마트포인터입니다. 이전에 작성한글이 있다.
스마트포인터는 두가지 특징이 있습니다.
1. 자원을 획득한 후에 자원 관리 객체에게 넘깁니다.
자원관리에 객체를 사용하는 아이디어에 대한 업계 용어도 자주 통용 되고 있는데 자원 획득 즉 초기화(Resource Acquition is Initialization : RAII) 라는 이름입니다. 요약하면 "자원을 획득하고 나서 바로 자원관리 객체에 넘겨준다"는 점은 같습니다.
2. 자원 관리 객체는 자신의 소멸자를 사용해서 자원이 확실히 해제되도록 합니다.
소멸자는 어떤 객체가 소멸될 때 자동적으로 호출되기 때문에, 실행 제어가 어떤 경위로 블록을 떠나는가에 상관없이 자원해제가 제대로 이루어지게 되는 것입니다.
void DoSomething()
{
//...
Character* newCharacter = Character::CreateCharacter();
std::shared_ptr<Character> newCharacter2(Character::CreateCharacter()); //추가
//..
delete newCharacter;
//newCharacter2는 해제 필요 x
}
정리
* 자원 누출을 막기 위해, 생성자 안에서 자원을 획득하고 소멸자에서 그것을 해제하는 RAII객체를 사용합시다.
* 일반적으로 널리쓰이는 RAII클래스는 unique 포인터, shared 포인터, weak 포인터가 있습니다.
'C & CPP > Effective C++' 카테고리의 다른 글
[CPP-effective] 3-3 자원 관리 클래스에서 관리되는 자원은 외부에서 접근가능하게 하자. (0) | 2021.04.08 |
---|---|
[CPP-effective] 3-2 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자. (0) | 2021.04.01 |
[CPP-effective] 2-7 객체의 모든 부분을 빠짐없이 복사하자. (0) | 2021.03.30 |
[CPP-effective] 2-6 operator=에는 자기대입에 대한 처리를 빼먹지 말자. (0) | 2021.03.30 |
[CPP-effective] 2-5 대입 연산자는 *this의 참조자를 반환하게 하도록 (0) | 2021.03.22 |