ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective C++...44
    일지 2022. 8. 22. 08:51

     타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자

    생성자를 통한 암시적 변환은 컴파일러에게 고려되지 않는다

    다음과 같이 생성자에서 암시적 형 변환을 하던 클래스를 템플릿으로 만들면 operator*에 사용되는 T가 무엇인지 알 수 없기 때문에 컴파일 에러가 발생하게 된다.


    template<typename T>

    class Rational {

    public:

        Rational(const T& numerator = 0, const T& denominator = 1);

        const T numerator() const;

        const T denominator() const;

    };

    template<typename T>

    const Rational<T> operator*(const Rational<T>& lhs, const Rational<T>& rhs)

    { ... }

     

    Rational<int> oneHalf(1, 2);

    Rational<int> result = oneHalf * 2; // 컴파일 에러 발생!


     

    컴파일 에러 발생하는 구간에서 oneHalf는 정상적으로 진입하지만 두 번째 인자인 2는 int가 되어 암시적으로 Rational<int>가 될 수 있지만 컴파일러는 이러한 암시적 변환을 신경 쓰지 않기에 에러가 발생한다.

     

    클래스 안에 비멤버 함수를 사용

    클래스 안에 비멤버 함수를 넣는 방법은 friend밖에 없기 때문에 friend함수를 이용해 operator*를 구현하면 위의 코드가 정상적으로 실행되게 된다.


    template<typename T>

    class Rational {

    public:

        // 클래스 내부에 선언 및 정의를 해줘야 한다.

        friend const Rational Operator*(const Rational& rhs, const Rational& lhs)

        {

            return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * hrs.denominator());

        }

    };


     

    friend 함수로 선언했다고 public 외의 접근 권한을 부여한다는 뜻은 아니다.

     

    댓글

Designed by Tistory.