[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "
" 모든 코드는 오직 '참조자에 의한 전달' 만으로 이루어져야 한다는 생각을 버리자! "
- 지역 스택 객체에 대한 포인터나 참조자를 반환하는 일, 혹은 힙에 할당된 객체에 대한 참조자를 반환하는 일, 또는 지역 정적 객체에 대한 포인터나 참조자를 반환하는 일은 그런 객체가 두 개 이상 필요해질 가능성이 있다면 절대로 하지말자!
[operator* 코드]
const Rational& operator*(const Rational& lhs, const Rational& Rhs) { Rational result(lhs.n * rhs.n, lhs.d * rhs.d); return result; }
생성자를 생성하기 싫어서 참조자를 반환하게 한건데 결국엔 객체를 생성해야 한다...
result는 스택에서 생성된 지역객체 이므로 함수가 종료되면 소멸한다!
- 이미 소멸한 객체가 있던 공간을 가리키는 곳을 반환해버리는 꼴...
[operator* 코드]
const Rational& operator*(const Rational& lhs, const Rational& Rhs) { Rational* result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d); return *result; }
예시 1과 마찬가지로 생성자가 호출된다..
new로 동적 할당 된 메모리는 언제, 누가 해제해 줄 것인가..?
📢 Rational w, x, y, z;
• • • w = x * y * z;
- operator* 호출이 두 번 일어났기에 new 와 delete도 두 번 일어나야 한다.
- x * ( y * z )의 참조자는 접근할 수 있어도, y * z 연산 후 반환된 참조자에는 접근할 수 없다...
=> 메모리 누출이 일어난다!
[operator* 코드]
const Rational& operator*(const Rational& lhs, const Rational& Rhs) { static Rational result; result = lhs.n * rhs.n, lhs.d * rhs.d; return result; }
마찬가지로 생성자가 호출된다.
또 다른 문제 발생!
Rational a, b, c, d;
if((a*b) == (c*d));
- operator*의 결과 값은 정적(static)객체인 result 이기 때문에 위 if 조건문은 항상 true가 된다...
[operator* 코드]
inline const Rational& operator*(const Rational& lhs, const Rational& Rhs) { return Rational(lhs.n * rhs.n, lhs.d * rhs.d); }