result = oneFourth * 2; result = 2 * oneFourth; // 멤버함수로 operator*를 선언할 경우 // 2.operator*(Rational)을 찾지 못하고 비멤버 함수를 검색하기 때문에 // 비멤버 함수가 없으면 에러가 발생합니다.
클래스의 공개 함수만으로 구현할 수 있는 함수는 굳이 friend함수로 하지 않는다.
항목 25. 예외를 던지지 않는 swap에 대한 지원도 생각해 보자.
표준에서 제공하는 swap이 납득할 만한 효율을 보이면 그냥 아무것도 하지 마십시오.
효율이 기대한 만큼 충분치 않다면 다음과 같이 하십시오. (ex)pimpl(pointer to implementation)와 유사한 경우)
효율적으로 맞바꾸는 함수를 public 멤버 함수로 두십시오
1 2 3 4 5 6 7 8 9 10 11
classWidget { public: ... voidswap(Widget& other)//효율적인 함수 { ... swap(pImpl, other.pImpl); } private: WidgetImpl* pImpl; //Widget의 실제 데이터를 가진 객체에 대한 포인터 };
같은 네임스페이스 비멤버 swap을 만들어 넣습니다. 그리고 1번에서 만든 멤버 함수를 호출합니다.
1 2 3 4 5 6
namespace WidgetStuff { voidswap(Widget& a, Widget& b) { a.swap(b); //멤버 함수 호출 } }
새로운 클래스 라면 std::swap의 특수화 버전을 준비해 둡니다.(클래스 템플릿일 경우 추가하지 않습니다.std에는 새로운 템플릿 추가를 금합니다.)
1 2 3 4 5 6
namespacestd { voidswap(Widget& a, Widget& b) { a.swap(b); } }
swap을 호출할 때, std::swap을 볼수 있도록 using 선언을 반드시 포합시킵니다.
1 2 3 4 5 6 7 8 9 10
template<typename T> voiddoSomething(T& obj1, T& obj2) { usingstd::swap; ... swap(obj1, obj2); // 1. T와 동일한 네임스페이스 안에 T 전용의 swap을 찾습니다. // 2. std::swap의 T 특수화 버전을 찾습니다. // 3. std::swap의 일반형 템플릿 함수를 호출합니다. ... }