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 인터페이스만을 이용해서 구현할 수 있기 때문이다.
즉, "멤버 함수의 반대는 프렌드 함수가 아니라 비멤버 함수이다" 라는 결론을 기억하자! 프렌드 함수를 남용하지 않도록 주의하는 것은 덤이다.
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 26 : 변수 정의는 늦출 수 있는 데까지 늦추는 근성을 발휘하자 (0) | 2022.10.25 |
---|---|
Effective C++ | 항목 25 : 예외를 던지지 않는 swap 에 대한 지원도 생각해 보자 (0) | 2022.10.25 |
Effective C++ | 항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자 (0) | 2022.10.25 |
Effective C++ | 항목 22 : 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 (0) | 2022.10.25 |
Effective C++ | 항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 (0) | 2022.10.25 |
Comments