본문 바로가기

C++38

보편참조에 대한 중복적재 대신 사용할수 있는 기법들 1 1. 중복적재를 포기한다 중복 적재 버전에 각자 다른 이름을 붙여 보편 참조에 대한 단점을 피할 수 있다. 하지만 생성자의 이름은 언어에 의해 고정되기 때문에 중복적재가 필요할 수 있다. 2. const T& 매개변수를 사용한다. 보편 참조 매개변수 대신 const에 대한 왼값 참조 매개변수를 사용한다. 이런 설계는 원하는 만큼 효율적이지 않다. 3. 값 전달 방식의 매개변수를 사용한다 참조 전달 매개변수 대신 값 전달 매개변수를 사용한다. 복사될 것이 확실한 객체는 값으로 전달하는 것을 고려하는 것이 좋다. 앞에 설명했던 예제의 Person을 사용해 결과를 보도록 하자 class Person { public: explicit Person(std::string n)// T&& 생성자를 대체한다 : nam.. 2020. 7. 22.
보편 참조에 대한 중복적재를 피하라 // 사람 이름 하나를 매개변수로 받고, 현재 날짜와 시간을 기록하여 전역 자료구조에 추가하는 예제 std::multiset names;// 전역 자료구조 void logAndAdd(const std::string& name) { auto now = std::chrono::system_clock::now();// 현재 시간을 얻고 log(now, "logAndAdd");// 로그에 기록 names.emplace(name);// 이름을 전역 자료구조에 추가 } std::string petName("Darla"); logAndAdd(petName);// 왼값 std::string을 넘겨줌 logAndAdd(std::string("Persephone"));// 오른값 std::string을 넘겨줌 logAnd.. 2020. 7. 21.
std::move, std::forward std::move와 std::forward는 캐스팅을 수행하는 함수(함수 템플릿)이다. std::move는 주어진 인수를 무조건 오른 값으로 캐스팅하고, std::forward는 특정 조건이 만족될 때에만 캐스팅을 수행한다. std::move를 구현해보자 template// C++11 버전 typename remove_reference::type&& move(T&& param) { using ReturnType = typename remove_reference::type&&; return static_cast(param); } template// C++14 버전, remove_reference_t와 decltype 사용 decltype(auto) move(T&& param) { using ReturnTy.. 2020. 7. 17.
Pimpl 관용구를 사용할 때에는 특수 멤버 함수들을 구현 파일에서 정리하라 Pimpl 관용구는 클래스의 자료 멤버들을 구현 클래스 또는 구조체를 가리키는 포인터로 대체하고, 일차 클래스에 쓰이는 자료 멤버들을 그 구현 클래스로 옮기고, 포인터를 통해 그 자료 멤버들에 간접적으로 접근하는 방법이다. 일반적으로 헤더의 의존도를 떨어뜨리고, 컴파일 시간을 단축해 준다. 기존 C++98에서의 구현 방법 예시이다. // "widget.h" class Widget { public: Widget(); ... private: std::string name; std::vector data;// 헤더 내에 #include , #include 필요 Gadget g1, g2, g3; }; // Pimpl 관용구 적용 class Widget { public: Widget(); ~Widget();// .. 2020. 7. 16.
new 보다 std::make_shared와 make_unique를 선호하라 std::make_shared는 C++11의 일부지만 std::make_unique는 C++14에 와서 표준 라이브러리에 포함되었다. 하지만 간단하게 구현할 수 있다. template// C++11 용으로 구현한 make_unique std::unique_ptr make_unique(Ts&&... params) { return std::unique_ptr(new T(std::forward(params)...)); } new 보다 make 함수를 선호해야하는 첫번째 이유로는 코드의 중복을 없애는데 있다. auto upw1(std::make_unique());// make 함수를 사용 std::unique_ptr upw2(new Widget);// 사용하지 않음 되풀이되는 Widget의 중복을 없앨 수 있다.. 2020. 7. 15.
std::weak_ptr std::weak_ptr은 std::shared_ptr에서의 문제점인 자신이 가리키는 대상이 이미 파괴되었을 수 있다는 문제를 극복 할 수 있다. std::weak_ptr는 역참조 할 수 없으며, 널인지 판정할 수도 없다. std::weak_ptr는 그 자체로 smart pointer가 아닌 std::shared_ptr를 보강하는 위치에 있기 때문이다. 대체로 std::weak_ptr는 std::shared_ptr를 이용해 생성한다. std::weak_ptr는 자신을 생성하는데 쓰인 std::shared_ptr가 가리키는 것과 동일한 객체를 가리키지만 그 객체의 참조 횟수에는 영향을 주지 않는다. 대상을 잃은 std::weak_ptr를 만료 되었다고 하며, expire를 호출함으로써 알 수 있게 된다. .. 2020. 7. 14.