예외를 던지지않는 swap(effective c++ 25)
2015. 8. 25. 17:40ㆍ프로그래밍/Effective C++
728x90
728x90
표준 제공 swap
복사만 제대로 지원하는 타입이면 어떤 타입의 객체이든 맞바꾸기 동작을 수행한다.
성능
swap의 내부에 객체를 넘기면 얄짤 없이 복사가 세 번이 일어난다. (엄청난 비효율)
pimpl기법
pointer to implementation이란 뜻으로 객체가 실제 데이터를 모두 가지고 있는 것이 아니라
이를 가리키는 포인터로 설계하는 기법.
비효율적 swap 호출
한번 복사에 복사 생성자와 대입연산자가 여러 번 호출한다.
특히 pImpl 기법이 사용되었다면 극도로 비효율적인 작업이 된다.
특수화 템플릿 swap
클래스의 swap으로 데이터가 가리키는 포인터만 서로 교환한다.
Wiget2의 완전 특수화 템플릿을 구성해주어 해당 클래스가 호출 될 때 이 특수화 함수가 호출 되도록 한다.
클래스 템플릿 swap
C++은 함수 템플릿에 대해선 부분 특수화를 허용하지만 클래스 템플릿에 대한 부분 특수화는 허용하지 않는다.
이렇게 함수 템플릿의 오버로딩으로 해결할 수 있다.
하지만! 이것도 컴파일 에러!!!! std는 템플릿에 대한 완전 특수화는 지원하지만
새로운 템플릿을 추가하는 것은 허용하지 않는다.
그러면 도데체 어떻게?
맴버 swap을 호출하는 비맴버 함수를 만들고, 이를 std::swap의 특수화 버전이나 오버로딩으로 선언하지 않는다.
이렇게 하면 된다!!
using std::swap을 통해
T타입 전용 버전이 없다면 std 일반형 버전으로, T 타입 전용 버전이 있다면 그것이 호출 되도록 할 수 있다.
해당 코드가 없다면 호출하는 함수는 세 개 중 하나이다.(불분명)
std에 있는 일반형(이것은 확실히 있다.)
std의 일반형을 특수화한 버전(있을 수도 있고, 없을 수도 있다.)
T타입 전용 버전(있을 수도 있고, 없을 수도 있다.)
정리
- std::swap이 구현 시 느리게 동작할 여지가 있다면 swap 멤버 함수를 제공하자.
이 swap은 예외를 던지지 않도록 만든다.
- 멤버 swap을 제공한다면, 이 멤버를 호출하는 비멤버 swap도 제공하자.
클래스(템플릿 아님)에 대해서는, std::swap도 특수화한다.
- 사용자 입장에서 swap을 호출할 때는, std::swap에 대한 using 선언을 넣어 준 후에
네임스페이스 한정 없이 swap을 호출하게 하자.
- 사용자 정의 타입에 대한 std 템플릿을 완전 특수화하는 것은 가능하다.
하지만 std에 어떤 것이라도 새로 추가하려 들지 말자.
728x90
반응형
'프로그래밍 > Effective C++' 카테고리의 다른 글
내부에서 사용하는 객체의 핸들을 반환하는 코드는 NO(effective c++ 28) (0) | 2015.09.04 |
---|---|
캐스팅 절약(effective c++ 27) (0) | 2015.09.04 |
변수 정의 최대한 늦추기(effective c++ 26) (0) | 2015.08.25 |
타입변환이 모든 매개변수에 적용된다면? 그 함수는 비멤버로(effective c++ 24) (0) | 2015.08.25 |
멤버 함수보단 비멤버 비프렌드 함수를!(effective c++ 23) (0) | 2015.08.25 |
데이터 멤버는 private(effective c++ 22) (0) | 2015.08.25 |
함수에서 객체 반환시 참조로 X(effective c++ 21) (0) | 2015.08.23 |