본문 바로가기
책 정리/Effective C++ 3rd

항목 24. 타입 변환이 모든 매개변수에 대해 적용되어야 한다면 비멤버 함수를 선언하자

by ocean20 2020. 1. 10.

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 포인터가 가리키는 객체포함) 대해 타입 변환이 필요하다면, '비멤버함수' 구성해라

댓글