[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "
" 클래스 안에 비멤버 함수를 선언하는 유일한 방법 '프렌드'! "
- 모든 매개변수에 대해 암시적 타입 변환을 지원하는 템플릿과 관계가 있는 함수를 제공하는 클래스 템플릿을 만들려고 한다면, 이런 함수는 클래스 템플릿 안에 프렌드 함수로서 정의하자!
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
는 Rational<int>
이기 때문에 T가 int 라는걸 알지만, 두번째 인자는 기본 int 형식이다. 암시적 변환이 고려되지 않기에 컴파일러는 알 수 없다.template<typename T>
class Rational
{
public:
...
friend
const Rational operator*(const Rational& lhs,
const Rational& rhs);
};
template<typename T>
const Rational<T> operator*(const Rational<T>& lhs,
const Rational<T>& rhs)
{ ... }
📢 컴파일은 되지만 링크가 되지 않는다!
- Rational 안에 선언만되고 정의는 되지 않았기에!
template<typename T>
class Rational
{
public:
friend const Rational operator*(const Rational& lhs,
const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
};
가장 간단한 방법
프렌드 함수를 선언 했지만 클래스의 public 영역이 아닌 부분에 접근하는 것과 프렌드 권한은 아무런 상관이 없다
- 공교롭게도 클래스 안에 비멤버 함수를 선언하는 유일한 방법이 '프렌드' 였을 뿐
template<typename T> class Rational;
template<typename T>
const Rational<T> doMultiply(const Rational<T>& lhs,
const Rational<T>& rhs);
template<typename T>
class Rational
{
public:
...
friend
const Rational<T> operator*(const Rational<T>& lhs,
const Rational<T>& rhs)
{ return doMultiply(lhs, rhs); }
...
};
template<typename T>
const Rational<T> doMultiply(const Rational<T>& lhs,
const Rational<T>& rhs)
{
return Rational<T>(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}