KoreanFoodie's Study

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

Tutorials/C++ : Advanced

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

GoldGiver 2022. 10. 25. 16:15

C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!

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

핵심 :

어떤 함수에 들어가는 모든 매개변수(this 포인터가 가리키는 객체도 포함해서) 에 대해 타입 변환을 해 줄 필요가 있다면, 그 함수는 비멤버이어야 한다.

 

유리수를 나타내는 클래스가 있다고 하고, 곱셉 연산을 만든다고 가정하자.

class Rational
{
  public:
    Rational(int numerator = 0, int denominator = 1);
    int numerator() const;
    int denominator() const;
    const Rational operator*(const Rational& rhs) const;
  private:
    int n;
    int d;
};

int Rational::numerator() const
{
  return n;
}

int Rational::denominator() const
{
  return d;
}

Rational::Rational(int numerator, int denominator)
{
  n = numerator;
  d = denominator;
}

const Rational Rational::operator*(const Rational& rhs) const
{
  return Rational(this->n*rhs.numerator(), this->d*rhs.denominator());
}

void printRational(const Rational& r)
{
  cout << r.numerator() << " / " << r.denominator() << endl;
}


int main()
{
  Rational oneEight(1, 8);
  Rational oneHalf(1, 2);
  
  Rational result = oneHalf * oneEight;
  printRational(result);

  return 0;
}

위 클래스는 다음과 같은 케이스를 처리할 수 없다!

// 이건 잘 된다
result = oneHalf * 2;
// 다음과 같이 변형
result = oneHalf.operator*(2);
// 암시적 변환 : 2 를 const Rational temp(2) 처럼...
result = oneHalf * temp;

// 이건 안 된다
result = 2 * oneHalf;
// 다음과 같이 변형 (정수의 operator* 멤버 함수 따위 없음)
result = 2.operator*(oneHalf);
// 컴파일러의 탐색.. 혹시 이런 게 있나? -> 탐색 실패!
result = operator*(2, oneHalf);

위의 코드 블록에서처럼, 혼합형 연산(e.g. 정수 * 유리수 클래스 연산)을 지원할 수 있도록 만드려면 다음과 같이 비멤버 함수를 선언해주면 된다.

const Rational operator*(const Rational& lhs, const Rational& rhs) const
{
  return Rational(lhs.numerator() * rhs.numerator(),
                  lhs.denominator() * rhs.denominator());
}

위의 함수는 지금의 예제에서는 프렌드 함수로 두면 안된다. 왜냐하면 Rational 클래스의 public 인터페이스만을 이용해서 구현할 수 있기 때문이다.

즉, "멤버 함수의 반대는 프렌드 함수가 아니라 비멤버 함수이다" 라는 결론을 기억하자! 프렌드 함수를 남용하지 않도록 주의하는 것은 덤이다.

Comments