KoreanFoodie's Study
Effective C++ | 항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 본문
Tutorials/C++ : Advanced
Effective C++ | 항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자
GoldGiver 2022. 10. 25. 16:13
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자
핵심 :
1. 지역 스택 객체에 대한 포인터나 참조자를 반환하는 일, 혹은 힙에 할당된 객체에 대한 참조자를 반환하는 일, 또는 지역 정적 객체에 대한 포인터나 참조자를 반환하는 일은 그런 객체가 두 개 이상 필요해질 가능성이 있다면 절대로 하지 말자(항목 4를 보면 단일 스레드 환경에서의 적절한 코드 예제를 찾을 수 있다)
유리수를 표현하는 클래스의 곱셈 operator 를 다음과 같이 정의하면, 각기 다른 문제가 발생한다!
// 1. result 객체를 생성 (스택 영역)
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational result(lhs.n * rhs.n, lhs.d * rhs.d);
// Dangling Pointer
// 지역변수인 result 는 소멸하는데, 이에 대한 참조자를 리턴!
return result;
}
// 2. result 객체를 생성 (힙 역역)
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational *result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d);
// Memory Leak
// new 로 생성한 result 는 어디에서 delete ...?
return *result;
}
// 3. 대환장 코드
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
static Rational result;
result = Rational(lhs.n * rhs.n, lhs.d * rhs.d);
return result;
}
// 3번을 사용하면...
Rational a, b, c, d;
...
if ((a*b) == (c*d))
{
// 위 if 식은 항상 true
// operator 의 결과값은 같은 static 객체인 result 일 것이기 때문!
}
올바른 코드는 다음과 같을 것이다.
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
}
위의 연산에 필요한 비용은 작은 비용이다. 나머지는 컴파일러의 최적화 능력을 믿어보도록 하자.
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자 (0) | 2022.10.25 |
---|---|
Effective C++ | 항목 22 : 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 (0) | 2022.10.25 |
Effective C++ | 항목 20 : '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다 (0) | 2022.10.25 |
Effective C++ | 항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자 (0) | 2022.10.25 |
Effective C++ | 항목 18 : 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 (0) | 2022.10.25 |
Comments