[C++ Core] 우측 값 레퍼런스(rvalue reference)
좌측 값과 우측 값
본 설명에 들어가기 전 좌측 값(혹은 좌변 값, left-value)과 우측 값(혹은 우변 값, right-value)이 무엇인지 먼저 알 필요가 있다. 좌측 값이란 대입 연산자 왼쪽에 올 수 있는 값들을 얘기한다. 즉, 메모리가 할당되는 대상들이다. 우측 값은 좌측 값을 제외한 모든 것을 얘기한다.
int i3 = 0; // i3는 좌측값, 0은 우측값이다. int i4 = i3; // i3는 여기서 우측값으로 사용된다. // 즉, i3 변수에 저장된 값이 사용되는 것이다.
우측 값 레퍼런스
우측 값 레퍼런스란, 이런 우측값들을 참조할 수 있다는 얘기다. 특히, 우측 값들 중 임시 값(혹은 임시 객체)들에 대해 의미가 있다.
그럼 우측 값 레퍼런스를 어디에 사용하는지 의문을 가질 수 있다. 상수 좌측 값 레퍼런스도 우측 값을 바인드할 수 있지 않은가? 하지만, 둘은 목적이 기본적으로 다르다.
- 우측값 레퍼런스는 복사본이 필요한 것을 최적화하기 위한 '파괴적인 읽기(destructive read)'를 구현하기 위해 사용한다.
- 상수 좌측값 레퍼런스는 인자의 수정을 막기 위해 사용한다.
즉 우측 값 레퍼런스는 이동 의미론(move semantic)을 지원하기 위한 기능이다. 우측 값 참조는 기존 참조에 &
을 하나 더해 &&
을 쓴다. 다음의 예를 보자.
이동 의미론이란?
이동 의미론이 무엇인지 살펴보기 전에 복사 의미론(copy semantic)을 먼저 살펴보자. 얕은 복사(swallow copy)와 깊은 복사(deep copy)라는 개념이 있다. 동적으로 할당된 메모리에 대해 주소만 복사하는 것을 얕은 복사, 새로 메모리에 할당 해 값을 복사하는 것을 깊은 복사라고 한다.
얕은 복사 깊은 복사 그런데, 이러한 연산이 부담 될 때가 있다. 가령 임시 객체의 값을 복사해오고자 한다면? 쓸데 없는 연산만 느는 셈이 될 것이다. 다시 말하면, 소유권을 이전하는 것이 더 효율적일 것이다. 이를 극복하기 위해 고안된 것이 이동 의미론이다. 이동 의미론은 값을 그대로 이동시키는 것을 말한다.이동 연산
class A { public: // ... // 이동 생성자 A(A&& other) : mSize{ other.mSize }, mData{ other.mData } // 새롭게 할당되는 것이 아니라 // 이동이 이루어진다. { // 이전에 있던 데이터는 정리해준다. mData = nullptr; } // 이동 할당 연산자 A& operator=(A&& other) { mSize = other.mSize; mData = other.mData; other.mData = nullptr; } // ... private: int mSize = 10; int* mData = new int[mSize]{ }; };
&&
연산자를 통해 우측 값(임시 개체)을 받는다는 것을 코드로 표현하였다. 또 C++에서는 해당 개체를 우측 값으로 만들어주는 헬퍼 함수인 std::move()
도 만들어 놓았다. 다음의 예를 보자.
template <typename T> void swap(T& lhs, T& rhs) { // 기존 swap은 T temp = lhs; 였다. // 하지만 이는 복사 연산이 이용되기에 매우 비쌌다. // 이제는 이동 연산 사용으로 비용을 좀 더 줄일 수 있다. T temp{ std::move(lhs) }; lhs = std::move(rhs); rhs = std::move(temp); }
이외에도 완벽한 전달(perfect forwarding)을 위해서도 사용될 수 있지만, 다음에 기회가 되면 서술하도록 하겠다.
'Outdated > Core Language' 카테고리의 다른 글
[C++ Core] 함수 개체(function object)와 람다 표현식(lambda expression) (0) | 2018.09.07 |
---|---|
[C++ Core] 상수 구문 - new 연산자 (0) | 2018.08.29 |
[C++ Core] 상수 구문 - const vs constexpr (0) | 2018.08.21 |
[C++ Core] POD(plain old data), 표준 레이아웃 타입(standard layout type), 간단한 타입(trivial type) (0) | 2018.08.17 |
[C++ Core] 타입 추론(type deduction) - auto와 decltype (0) | 2018.08.13 |