1. 소유권 독점 자원의 관리에는 std::unique_ptr를 사용하라
std::unique_ptr: 독점 소유권 의미론을 가진 자원의 관리를 위한, 작고 빠른 이동 전용 스마트 포인터
- 생 포인터와 같은 크기
- 널이 아닌 항상 자신이 가리키는 객체를 소유(즉, 이동 시 소유권이 원본 포인터에서 대상 포인터로 옮겨짐)
- 복사가 허용되지 X
- 널이 아닌 std::unique_ptr는 소멸 시 자신이 가리키는 자원을 파괴
- 개별 객체를 위한 것(std::unique_ptr<T>)과 배열을 위한 것(std::unique_ptr<T[]>)으로 분류
- 기본적으로 자원 파괴는 delete를 통해 일어나나, 커스텀 삭제자를 지정 가능
ex)
- std::unique_ptr를 std::shared_ptr로 손쉽게 변환 가능
ex)
2. 소유권 공유 자원의 관리에는 std::shared_ptr를 사용하라
std::shared_ptr: 공유 포인터로서 공유 자원의 수명을 편리하게 관리할 수 있는 수단 제공하는 포인터
- std::unique_ptr 크기의 두 배이다
- 기본적으로 delete를 통해 파괴, 커스텀 삭제자 지원. 삭제자의 타입은 영향 미치지 X
- 참조 카운트를 담을 메모리를 반드시 동적으로 할당
- 생 포인터 타입의 변수로부터 std::shared_ptr를 생성하는 일은 피해야 한다.
ex) 잘못된 용법
- std::shared_ptr 생성자에 생포인터를 넘겨주는 일은 피하라
- std::shared_ptr 생성자를 생 포인터로 호출할 수밖에 없는 상황이라면, 생 포인터의 변수를 거치지 말고 new의 결과를 직접 전달하라.
->같은 생 포인터로 또 다른 std::shared_ptr를 생성하려는 유혹에 빠질 염려가 없다.
- std::shared_ptr를 std::unique_ptr로 바꾸는 것은 불가능
3. std::shared_ptr처럼 작동하되 대상을 잃을 수도 있는 포인터가 필요하면 std::weak_ptr를 사용하라
- std::weak_ptr는 자신을 생성하는 데 쓰인 std::shared_ptr가 가리키는 것과 동일한 객체를 가리킴
- std::weak_ptr의 만료 여부는 멤버 함수 expired가 돌려주는 값으로 판단
- std::weak_ptr 역참조 방법
std::weak_ptr로부터 std::shared_ptr를 얻고 그 std::shared_ptr을 역참조한다.
- lock 멤버 함수를 사용
- std::shared_ptr의 생성자에 std::weak_ptr를 넘겨줌
- 잠재적인 용도로는 캐싱, 관찰자 목록, 그리고 std::shared_ptr 순환 고리 방지가 있음
4. new를 직접 사용하는 것보다 std::make_unique와 std::make_shared를 선호하라
make 함수 장점
- 소스 코드 중복의 여지가 없어짐
- 예외 안전성 향상
- 컴파일러가 좀 더 간결한 자료구조를 사용하는 더 작고 빠른 코드를 산출
make 함수 특징
- 커스텀 삭제자를 지정하는 기능 X
- 매개변수들을 완벽 전달할 때 중괄호가 아니라 괄호를 사용
5. Pimpl 관용구를 사용할 때에는 특수 멤버 함수들을 구현 파일에서 정의하라
Pimpl 관용구 효과
클래스 구현과 클래스 클라이언트 사이의 컴파일 의존성을 줄임으로써 빌드 시간을 감소
std::unique_ptr 형식의 pImpl 포인터를 사용할 때에는 특수 멤버 함수들을 클래스 헤더에 선언하고 구현 파일에서 구현해야 함
위의 조언은 std::unique_ptr에 적용될 뿐, std::shared_ptr에는 적용되지 X
'modern effective c++' 카테고리의 다른 글
effective modern c++ chap.3 (0) | 2020.02.24 |
---|---|
effective modern c++ chap.2 (0) | 2020.02.17 |