스콧 마이어스의 Effective C++을 읽고 개인 공부 목적으로 요약 작성한 글입니다!
💡 어떤 함수에 들어가는 모든 매개변수(this 포인터가 가리키는 객체도 포함)에 대해 타입 변환을 해 줄 필요가 있다면, 그 함수는 비멤버 함수여야 한다!
생성자를 explicit으로 선언하지 않으면 암시적 변환을 허용해준다.
class Rational {
public:
Rational (int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;
private:
...
};
이런 유리수 클래스가 있다고 하면,
생성자를 explicit으로 선언하지 않았으니까
int에서 Rational로 암시적 변환을 허용해준다.
유리수 클래스니까 곱셈 연산을 지원하도록 하고 싶으니
구현해보자
class Rational {
public:
...
const Rational operator* (const Rational& rhs) const;
};
이렇게 하면
Rational oneEight(1, 8);
Rational oneHalf(1, 2);
Rational result = oneHalf * oneEight; // OK
result = result * oneHalf; // OK
result = oneHalf * 2; // OK
result = 2 * oneHalf; // ERROR
이런 상황이 펼쳐진다.
당연히 Rational * Ratinal
은 가능하고
Rational * int
는 int를 Rational로 암시적으로 변환해줘서 가능하다.
즉, result = oneHalf * 2
는
result = oneHalf.opeator*(2);
를 의미하고,
암시적인 변환을 허용하기 때문에
const Rational temp(2);
result = oneHalf * temp;
이 되는거다.
당연히 된다.
근데 result = 2 * oneHalf;
는
result = 2.opeator*(oneHalf);
를 의미하는데
2는 정수.
정수에는 operator*
가 구현되어 있지 않으니
컴파일에러가 뜰거다.
비멤버 버전의 operator*
도 없을거다.
현재 int와 Rational의 비멤버 operator는 안해줬으니까.
만약 Rational 생성자가 explicit으로 선언된 명시 호출 생성자라면
result = oneHalf * 2
result = 2 * oneHalf
둘 다 컴파일되지 않았을거다.
매개변수에 대해 암시적 타입 변환을 하려면 매개변수 리스트에 있어야 한다
호출되는 멤버함수를 갖고 있는 (this가 가리키는) 객체에 해당하는 매개변수에는 암시적 변환이 먹히지 않는다.
멤버함수를 호출하는 그 객체는 암시적 변환이 되지 않는다는거다.
result = 2 * 3
이면
result = 2.opeator*(3)
이잖아
3은 Rational로 암시적 변환 될 수도 있지만
opeator* 멤버함수를 호출하는 객체인 2는 Rational로 암시적변환될 수 없다는거다.
그래서
operator*를 비멤버함수로 만들어보자
operator*을 비멤버 함수로 만들어서
모든 인자에 대해 암시적 타입 변환을 할 수 있도록 해주자
class Rational {
...
};
const Rational opeator* (const Rational& lhs, const Rational& rhs) { ... };
Rational oneFourth(1,4);
Rational result;
result = oneFourth * 2; // OK
result = 2 * oneFourth; // OK
ㅇㅋ??
이렇게 비멤버 함수로 만들면
lhs, rhs 모든 인자에 대해 암시적 타입 변환을 해줄 수 있다.
그래서 자연스럽게
가능하다
헤헤
멤버함수의 반댓말은 프렌드 함수가 아니다.
프렌드 함수는 피할 수 있으면 피하자.
위 opeator*는 Rational의 public 인터페이스만을 써서 구현할 수 있으므로
friend함수가 아니라 비멤버 함수로 만들어야 한다.
😊
C++시간에 제일 열심히 공부했던 부분..!!
연산자 오버로딩에서 제일 흥미로웠던 부분이다
1학년때 배웠던건데 아직도 재밌어..
explicit 생성자에 대해 확실히 이해할 수 있었다
굿.