본문 바로가기

전체 글50

22. Pimpl 관용구를 사용할 때에는 특수 멤버 함수들을 구현파일에서 정의하라. - Pimpl 관용구는 클래스 구현과 클래스 클라이언트 사이의 컴파일 의존성을 줄임으로써 빌드 시간을 감소한다. 예를 들어 다음과 같은 모습의 Widget 클래스가 있다고 하자. // "Widget.h" 헤더 파일 안에서 class Widget { public: Widget(void); private: std::string name; std::vector data; Gadget g1, g2, g3; // Gadget은 어떤 사용자 정의 타입 }; Widget의 데이터 멤버들이 std::string, std::vector, Gadget 타입이므로, Widget을 컴파일하려면 그 타입들의 헤더가 있어야 한다. 즉, Widget의 클라이언트는 반드시 #include를 이용해서 , , gadget.h 를 포함해.. 2021. 3. 13.
21. new를 직접 사용하는 것보다 std::make_unique와 std::make_shared를 선호하라. - new의 직접 사용에 비해, make 함수를 사용하면 소스 코드 중복의 여지가 없어지고, 예외 안전성이 향상되고, std::make_shared와 std::allocate_shared의 경우 더 작고 빠른 코드가 산출된다. std::make_shared는 C++11의 일부이지만, std::make_unique는 C++14에서야 표준 라이브러리에 포함되었다. 하지만 C++11 환경에서 make_unique와 같은 일을 하는 함수 템플릿을 만드는 것은 어렵지 않다. template std::unique_ptr make_unique(Ts&&... params) { return std::unique_ptr(new T(std::forward(params)...)); } 완전한 기능을 갖춘 make_unique.. 2021. 3. 12.
20. std::shared_ptr 처럼 작동하되 대상을 잃을 수 도 있는 포인터가 필요하면 std::weak_ptr을 사용하라. - std::shared_ptr처럼 작동하되 대상을 잃을 수도 있는 포인터가 필요하면 std::weak_ptr를 사용하라. 대체로 std::weak_ptr는 std::shared_ptr를 이용해서 생성한다. std::weak_ptr는 자신을 생성하는 데 쓰인 std::shared_ptr가 가리키는 것과 동일한 객체를 가리키나, 그 객체의 참조 카운트에는 영향을 주지 않는다. 대상을 잃은 std::weak_ptr를 가리켜 만료되었다(expired)라고 말한다. std::weak_ptr의 만료 여부는 멤버 함수 expired가 돌려주는 값으로 판단할 수 있다. 만료되지 않은 std::weak_ptr이라고 해도 피지칭 객체에 직접 접근하는 것은 불가능하다. std::weak_ptr에는 역참조 연산이 없기 때문.. 2021. 3. 11.
19. 소유권 공유 자원의 관리에는 std::shared_ptr을 사용하라. - std::shared_ptr는 임의의 공유 자원의 수명을 편리하게(가비지 컬렉션에 맡길 때만큼이나) 관리할 수 있는 수단을 제공한다. std::shared_ptr가 할 수 없는 일로는 배열 관리가 있다. std::unique_ptr와는 다르게, std::shared_ptr의 API는 단일 객체를 가리키는 포인터만 염두에 두고 설계되었다. std::shared_ptr로 배열을 가리키되, 배열 삭제를 수행하는 커스텀 삭제자를 지정하면 되지 않겠느냐는 발상을 할 수도 있다. 그런 코드가 컴파일되긴 하지만, 그리 좋은 발상은 아니다. 한 가지 이유는, std::shared_ptr는 operator[]를 제공하지 않는다는 것이다. 또 다른 이유로, std::shared_ptr가 지원하는 파생 클래스 포인터에서.. 2021. 3. 9.