Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 복사 생략(Copy Elision)과 반환 값 최적화(RVO)란 무엇일까?

복사 생략(Copy Elision)복사 생략(Copy Omission)이라고도 불리며, 컴파일러가 불필요한 객체 복사를 제거하는 대표적인 최적화 기법입니다. 현재 사용되는 거의 모든 C++ 컴파일러는 이 기술을 기본적으로 지원하고 있으며, 특히 객체를 반환하거나 초기화할 때 성능 향상에 큰 도움을 줍니다.

그렇다면 복사 생략은 실제로 어떻게 동작할까요? 아래 예제 코드를 통해 살펴보겠습니다.

예제 코드

#include <iostream>
using namespace std;
class MyClass {
   public:
   MyClass(const char* str = "\0") { //기본 생성자
      cout << "Constructor called" << endl;
   }
   MyClass(const MyClass &my_cls) { //복사 생성자
      cout << "Copy constructor called" << endl;
   }
};
main() {
   MyClass ob = "copy class object";
}

실행 결과

Constructor called

흥미로운 점은 실행 결과에 복사 생성자가 호출되지 않았다는 것입니다. 그 이유는 무엇일까요?

왜 복사 생성자가 호출되지 않았을까?

원래대로라면 문자열 리터럴로 객체를 초기화할 때 다음과 같은 과정이 일어납니다.

  1. 임시 객체가 먼저 생성됩니다.
  2. 생성된 임시 객체가 실제 객체 ob로 복사됩니다.

즉, 내부적으로는 아래 코드와 같이 동작해야 합니다.

MyClass ob = "copy class object";

위 코드는 사실상 다음과 동일한 의미입니다.

MyClass ob = MyClass("copy class object");

만약 컴파일러가 최적화를 수행하지 않는다면 임시 객체 생성 후 복사 생성자가 호출되어 "Copy constructor called" 메시지가 출력되어야 합니다. 하지만 C++ 컴파일러는 이러한 불필요한 오버헤드를 인지하고, 임시 객체를 곧바로 대상 객체에 직접 생성함으로써 복사 단계 자체를 생략합니다. 이것이 바로 복사 생략(Copy Elision)입니다.

정리

  • 복사 생략은 컴파일러가 임시 객체의 불필요한 복사를 제거하는 최적화 기법입니다.
  • C++17부터는 일부 상황(임시 객체 반환 등)에서 복사 생략이 표준에 따라 필수(mandatory)로 적용됩니다.
  • 반환 값 최적화(RVO, Return Value Optimization)는 함수가 객체를 값으로 반환할 때 복사 생략이 적용되는 대표적인 경우입니다.

결론적으로, 복사 생략 덕분에 개발자는 코드의 가독성을 유지하면서도 컴파일러가 자동으로 성능을 최적화해 주는 이점을 누릴 수 있습니다.