1. 타입변환 예시
이전 내용에서 암시적 타입변환을 지원하는 것은 좋지 않다.라는 내용을 기억할 수 있다.
하지만 가장 흔한 예외 중 하나가 숫자 타입을 만들때이다.
class Rational {
public :
Rational(int numerator = 0, int denominator = 1); //암시적 변환을 위해 explicit을 쓰지 않음
int numerator() const;
int denominator() const;
private :
...
};
*풀이
(1) 유리수 클래스이다.
(2) operator * 코드는 클래스 내부에 써주는게 좋을 것 같다는 판단이 나온다. 밑에서 확인해보자.
2. 클래스 내부에 operator * 작성
class Rational {
public:
…
const Rational operator*(const Rational& rhs) const;
};
...
Rational oneEighth(1,8);
Rational oneHalf(1,2);
Rational result = oneHalf * 2; // 정상코드
result = 2 * oneHalf; // 에러코드
...
*풀이
- 정상코드 : operator*의 매개변수에 2를 대입하면 암시적 변환으로 임시객체 Rational가 만들어져 문제없다.
- 에러코드 : int 2의 opeartor * 매개변수리스트에는 Rational 타입이 없다. -> 에러발생 -> 컴파일러는 호환가능한 비멤버버전의 operator*을 찾게된다.
* 결론
- this가 가리키는 객체에 해당하는 암시적 매개변수리스트에 동일한 타입이 없다면, 암시적 변환이 먹히지 않는다.
(ex. int의 operator *의 매개변수에는 Rational 타입이 없다. -> 암시적 변환 불가능함)
3. 해결방법
class Rational{
…
};
const Rational operator*(const Rational& lhs, const Rational& rhs) // 비멤버 함수
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator()); // Rational의 public 멤버만 사용해서 연산이 가능하다.
};
* 풀이
- 비멤버버전의 operator* 코드를 작성하였다. ( 모든 매개변수에 대한 타입 변환을 위해 )
- 굳이 friend 쓸필요없다.. 위 주석처럼 Rational의 public 멤버만으로 사용가능하므로..
요약정리
(1) 어떤함수에 들어가는 모든 매개변수(this 포인터가 가리키는 객체포함)에 대해 타입 변환이 필요하다면, '비멤버함수'로 구성해라
'책 정리 > Effective C++ 3rd' 카테고리의 다른 글
항목 26. 변수 정의는 늦출 수 잇는 데까지 늦추는 근성을 발휘하자 (0) | 2020.01.15 |
---|---|
항목 25. 예외를 던지지 않는 swap에 대한 지원도 생각해보자 (0) | 2020.01.13 |
항목 23. 멤버함수 보다는 비멤버 비프렌드 함수와 더 가까워지자 (0) | 2020.01.09 |
항목 22. 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 (0) | 2020.01.09 |
항목 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 (0) | 2020.01.08 |
댓글