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

Minsu._.Lighting·2023년 12월 1일
0

[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "

[핵심]

" 멤버 함수의 반대는 프렌드 함수가 아니라 비멤버 함수이다. "

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

💡 예시, 유리수를 나타내는 클래스

[예시 코드]

class Rational
{
public:
	Rational (int numerator = 0, int denominator = 1);

	int numerator() const;
	int denominator() const;
};
  • 책은 "클래스에서 암시적 타입변환을 지원하는 것은 일반적으로 못된 생각이다." 라고 소개되었으나 숫자 타입의 클래스를 만들 때의 경우에는 예외.
    - 정수에서 유리수로의 암시적 변환을 허용 하더라도 심각한 문제는 발생하지 않을테니까
    ( 기본 제공 타입인 int -> double 변환 처럼 )

📌 operator*를 만들어 보자!

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번 코드에서는 암시적 변환이 왜 일어나지 않는가?
- 호출되는 멤버 함수를 갖고 있는 객체에 해당하는 암시적 매개 변수에는 암시적 변환이 적용되지 않기 때문


📌 동작도 일관 되게 유지하고, 혼합형 수치 연산도 제대로 지원하는 operator*를 만들자!

[예시 코드]

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;
  • operator*를 비멤버 함수로 만들어서, 컴파일러 쪽에서 모든 인자에 대해 암시적 타입변환을 수행하도록 하자!

profile
오코완~😤😤

0개의 댓글

관련 채용 정보