[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "
" 멤버 함수의 반대는 프렌드 함수가 아니라 비멤버 함수이다. "
- 어떤 함수에 들어가는 모든 매개변수(this 포인터가 가리키는 객체도 초함해서)에 대해 타입 변환을 해 줄 필요가 있다면, 그 함수는 비멤버이어야 합니다.
[예시 코드]
class Rational { public: Rational (int numerator = 0, int denominator = 1); int numerator() const; int denominator() const; };
- 책은 "클래스에서 암시적 타입변환을 지원하는 것은 일반적으로 못된 생각이다." 라고 소개되었으나 숫자 타입의 클래스를 만들 때의 경우에는 예외.
- 정수에서 유리수로의 암시적 변환을 허용 하더라도 심각한 문제는 발생하지 않을테니까
( 기본 제공 타입인 int -> double 변환 처럼 )
const Rational operator*(const Rational& rhs) const; Ratinal oneEighth(1, 8); Ratinal oneHalf(1, 2);
예시 1. 유리수 곱셈
Rational result = oneHalf * oneEighth
result = result * oneEighth
예시 2. 혼합형 수치 연산
1. result = oneHalf * 2
2. result = 2 * oneHalf
- 1번 코드는 oneHalf가 멤버 함수로 operator를 갖고있어 호출이 가능!
- 2번 코드는 클래스가 아니기에 멤버 함수가 있을리 없고, 컴파일러는 비멤버 버전의 operator* 도 찾아 보았으나 int와 Rational을 받는 버전은 없기에 에러 발생!
📢 oneHalf의 operator*는 Rational 타입을 받게 했는데 어떻게 int인 2를 받았나?
- 암시적 변환을 일으켜 int를 Rational로 바꿔 받음.
- explicit로 생성된 생성자였다면 암시적 변환이 막혀 해당 코드는 사용하지 못했을 것
const Rational temp(2); // 임시 객체 생성 result = oneHalf * temp;
📢 그럼 2번 코드에서는 암시적 변환이 왜 일어나지 않는가?
- 호출되는 멤버 함수를 갖고 있는 객체에 해당하는 암시적 매개 변수에는 암시적 변환이 적용되지 않기 때문
[예시 코드]
class Rational { ... //operator* 가 없다! ... }; const Rational operator*(const Rational& lhs, const Rational& rhs) // 비멤버 함수 { return Raitonal(lhs.numerator() * rhs.numrator(), rhs.denominator() * rhs.denominator()); } Rational oneFourth(1, 4); Rational result; result = oneFourth * 2; result = 2 * oneFourth;