프로그래밍/C\C++

[Effective C++ 정리 #10] 대입 연산자의 return *this의 의미?!

허구의 2025. 6. 20. 07:24
728x90

이 글은 『Effective C++』를 읽고 개인적으로 공부한 내용을 정리한 기록입니다.

저는 컴퓨터공학을 전공하지 않았으며, 프로그래밍을 공부하는 과정에서의 이해와 생각을 정리하기 위해 글을 작성하고 있습니다.

따라서 내용 중 일부에 오류나 부정확한 설명이 있을 수 있으며, 피드백은 언제든지 환영합니다. 확인 후 수정하도록 하겠습니다.

전문적인 해설이 아닌 개인적 시선에서의 정리임을 참고하고 읽어주시면 감사하겠습니다.

[Effective C++ 정리 #10] 대입 연산자는 항상 *this를 반환하라

C++에서 연산자 오버로딩을 구현할 때, 특히 operator= 같은 대입 연산자를 다룰 땐 반환값으로 *this를 참조 형태로 리턴하는 것이 관례입니다. 이것은 단순한 스타일이 아니라, 문법과 기능적인 측면 모두에서 매우 중요한 역할을 합니다.


왜 꼭 return *this;를 써야 할까?

C++에서는 다음과 같은 코드를 자주 보게 됩니다:

int x, y, z;
x = y = z = 15; // 연쇄 대입(chain assignment)

 

이 코드는 다음과 같이 해석됩니다:

x = (y = (z = 15));

 

즉, 오른쪽부터 왼쪽으로 값이 대입되면서, 각 대입 연산자는 결과로 대입된 왼쪽 값을 반환합니다. 이 패턴은 기본 타입뿐 아니라, 사용자 정의 타입에도 동일하게 적용되길 기대합니다.

 

그렇기 때문에 우리는 다음처럼 구현해야 합니다:

class Widget {
public:
    Widget& operator=(const Widget& rhs) {
        ...
        return *this; // 자기 자신을 참조로 반환
    }
};

 

이렇게 해야 다음 코드도 자연스럽게 작동하죠:

Widget a, b, c;
a = b = c; // 연쇄 대입

이 규칙은 +=, -= 같은 연산자에도 적용된다

operator+=, operator-= 등 복합 대입 연산자도 동일한 규칙을 따릅니다:

class Widget {
public:
    Widget& operator+=(const Widget& rhs) {
        ...
        return *this;
    }

    Widget& operator=(int value) {  // 매개변수가 다른 경우에도
        ...
        return *this;
    }
};

 

즉, 매개변수 타입이 정수이든 객체이든 상관없이, 모든 대입 연산자는 자신을 참조로 반환하는 것이 표준입니다.


꼭 따라야 하나요? 

이건 강제되는 문법은 아닙니다. 즉, void operator=(const T& rhs) 처럼 void로 작성해도 컴파일은 됩니다. 하지만 그렇게 하면 위에서 말한 연쇄 대입이나 표준 라이브러리 호환성에서 문제가 발생할 수 있다고 합니다.

 

C++ 표준 라이브러리의 모든 타입들(e.g. std::string, std::vector, std::shared_ptr)도 이 규칙을 따르기 때문에, 따라서 사용자 정의 타입도 같은 방식으로 동작해야 일관성을 유지할 수 있습니다!


핵심 요약

  • 모든 대입 연산자는 *this를 참조 형태로 반환해야 한다.

감사합니다.

728x90