본문 바로가기

프로그램언어/Effective C++

항목 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자.

예를 들어 유리수를 나타내는 클래스가 있고 두 유리수를 곱하는 멤버함수가 있다고 합니다.


        class Rational {
                public :
                        Rational (int numerator = 0, int denominator = 1); 
                        .....
                private:
                        int n, d;
                
                friend
                        const Rational operator*(const Rational& lhs, const Rational& rhs);
        };

        Rational a(1, 2); // a = 1/2
        Rational b(3, 5); // b = 3/5

        Rational c = a * b; // c는 3/10 이란 결과가 나오길 바란다.

위 소스의 결과를 얻고 싶을 때 const Rational operator* 를..

        const Rational& operator*(const Rational& lhs, const Rational& rhs)
        {
                Rational result(lhs.n* rhs.n, lhs.d* rhs.d);
                return result;
        }

이런 지역객체를 반환하는 실수는 있으면 안됩니다. new 로 메모리를 할당해서 그 참조자를 반환하는 것도 해제를 보장할 수 없기 때문에 마찬가지로 사용하지 않는게 좋습니다.

그렇다고 static객체를 선언해서 반환해서도 안됩니다. (정적 객체이기 때문에 제대로 된 연산이 될 수 없습니다.)

이럴 땐 아래와 같이 처리하는 편이 낫습니다.

        inline const Rational operator*(const Rational& lhs, const Rational& rhs)
        {
                return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
        }

함수에서 객체를 반환해야 할 경우 내부에서 생성된 객체의 참조자를 반환하려 들지 말고 새로운 객체를 반환하도록 하는 합시다. (참조자가 아니라 복사되도록 했습니다.)

        char* UnitMaster::GetMasterTypeToString()
        {
                static char szLog[MAX_PATH];

                if(m_mtMasterType == MTYPE_RANDOR)
                {
                        sprintf(szLog, "란돌");
                }
                else if(m_mtMasterType == MTYPE_AFELEIA)
                {
                        sprintf(szLog, "아펠리아");
                }
                else if(m_mtMasterType == MTYPE_JANETH)
                {
                        sprintf(szLog, "자네스");
                }
                else if(m_mtMasterType == MTYPE_KAI)
                {
                        sprintf(szLog, "카이");
                }
                return szLog;
        }