[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "
" 반드시 클래스에 대해 표준 swap 함수를 특수화 해야 하는 경우가 생기므로 그 방법을 알아두자! "
- 표준 swap이 사용자 정의 타입에 대해 느리게 동작할 여지가 있다면 swap 멤버 함수를 제공하자!
(이 멤버 swap은 예외를 던지지 않도록 만들자)- 멤버 swap을 제공했으면, 이 멤버를 호출하는 비멤버 swap도 제공하자.
- 클래스에 대해서는 표준 swap도 특수화 하자!
- 사용자 입장에서 swap을 호출할 때 표준 swap에 대한 using 선언을 넣어준 후 네임스페이스 한정 없이 swap을 호출하자
- 사용자 정의 타입에 대한 std 템플릿을 완전 특수화 하는 것은 가능하다, 하지만 std에 어떤 것이라도 새로 '추가' 하려 들지는 말자
초창기 STL에 포함된 이래 '예외 안전성 프로그래밍에 없어선 안 될 감초역할
자기대입 현상의 가능성에 대처하기 위한 대표적인 메커니즘
[표준 swap 코드]
namesapce std
{
tmeplate<typename T>
void swap(T& a, T& b)
{
T temp(a);
a = b;
b = temp;
}
}
[멤버 swap 코드]
class Widget
{
...
public:
void swap(Widget& other)
{
using std::swap;
swap(pImp1, other.pImp2);
}
...
};
표준 swap의 효율이 기대한 만큼 충분치 않다면 사용하자!
- 사용자 정의 타입의 두 객체의 값을 맞바꾸는 함수를 swap이라는 이름으로 만들고 public 멤버 함수로 둠
멤버 버전의 swap은 반드시 예외를 발생시켜서는 안된다.
- 클래스가 강력한 예외 안전성 보장을 제공하도록 도움을 주는 방법이 있는데, 해당 방법은 swap이 예외를 발생시키지 않는다는 가정을 깔고 있기 때문이다.
- [ 항목 29 : 예외 안정성이 확보되는 그날 위해 싸우고 또 싸우자! ] 참고
[비멤버 swap 코드]
namesapce WidgetStuff
{
...
tmeplate<typename T>
void swap(Widget<T>& a, Widget<T>& b)
{
a.swap(b);
}
}
[표준 swap 코드]
namesapce std
{
tmeplate<>
void swap<Widget>(Widget& a, Widget& b)
{
a.swap(b);
}
}
새로운 클래스를 만들고 있다면(클래스 템플릿은 제외) 해당 클래스에 대한 표준 swap의 특수화 버전을 준비해 두자
특수화 버전에서도 멤버 swap을 호출
[swap 호출 코드]
tmeplate<typename T>
void doSomething(T& obj1, T& obj2)
{
using std:swap;
...
swap(obj1, obj2);
...
}
사용자 입장에서 swap을 호출할 때, swap을 호출하는 함수가 표준 swap을 볼 수 있도록 using 선언을 반드시 포함 시키자
swap을 호출 하되, 네임스페이스 한정자를 붙이지 않도록 하자