반응형
자 이번 항목은 암시적 변환을 허용하는 클래스에 대한 내용이다. 우선 아래와 같은 타입의 클래스가 있다고 치자.
class Rational {
public:
Rational(int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;
private:
...
};
대충 분수를 나타내는 클래스이다. 우리는 여기서 각 Rational 과의 곱셈을 할 수 있도록 하기 위해서 operator*를 멤버함수로 만들수 있다.
class Rational {
public:
...
const Rational operator*(const Rational& rhs) const;
};
자, 이렇게 되면 우리는 아래와 같은 식을 작성 할 수도 있다.
Rational oneEighth(1, 8);
Rational oneHalf(1, 2);
Rational result = oneHalf * oneEighth;
result = result * oneEighth;
자, 그런데 우리는 곱셈을 좀더 자연스럽게 하기위해 정수와의 곱셈도 허용하고 싶다. 그래서 우리는 아래와 같은 코드를 작성했다.
result = oneHalf * 2; // 정상 작동
result = 2 * oneHalf; // 오류!
하지만 두번째 줄에서 오류가 발생한다. 그 이유는 아래 코드를 보면 바로 이해 될 것이다.
result = oneHalf.operator*(2); // 정상 작동
result = 2.operator*(oneHalf); // 오류!
자, int의 operator*는 당연히 Rational 클래스에 대해서는 작동하지 않는다. 그렇다면 어떻게 해야 할까? 바로 비 멤버 함수를 만들어 버리는 것이다. 비멤버 함수로 선언한 후 2가 Rational로 암시적 변환이 된다면 정상 작동 할 것이다.
class Rational {
...
};
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
}
Rational oneFourth(1, 4);
Rational result;
result = oneFourth * 2;
result = 2 * oneFourth;
자, 그리고 여기서 한 가지 기억해야 할점은 멤버 함수의 반대는 프렌드 함수가 아니라 비멤버 함수라는 점이다. 프렌드를 통해 이점을 얻는 것보다 프렌드를 통해 골치 아픈 점이 더 많으니 유의 하도록 하자.
반응형
'C++ > Effective C++' 카테고리의 다른 글
항목 25 예외를 던지지 않는 swap에 대한 지원도 생각해 보자 (0) | 2024.01.24 |
---|---|
항목 23 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자 (0) | 2024.01.21 |
항목 22 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 (1) | 2024.01.21 |
항목 21 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 (1) | 2024.01.21 |
항목 20 '값에 의한 전달'보다는 '상수객체 참조자에 의한 전달'방식을 택하는 편이 대개 낫다 (2) | 2024.01.20 |