이동생성자 및 이동대입연산자
값의 분류
lvalue
임시적인 지속되는 것인 아닌, 정해진 시간 동안 지속되는 값
일반적으로 사용되는 변수가 lvalue 이다.
ex) 이름이 있는 변수, const 변수, 배열 변수, 클래스 멤버 등..
rvalue
임시적으로 지속되는 값
정의 하기가 상당히 모호하다 ..
ex) 리터럴(문자열 리터럴 제외), 함수의 리턴 값을 변수에 저장할 때, 값을 넣기 전 임시적으로 저장되는 값
rvalue 참조 연산자(&&)
c++11 이후 새로 나온 연산자
기존의 & 연산자는 lvalue 참조에 사용
&& 연산자는 rvalue 참조에 사용

std:move()
rvalue 의 참조를 반환
lvalue 를 rvalue 로 반환 -> lvalue 가 아닌, rvalue 를 사용한다는 것은 메모리 복사가 필요 없다는 것을 뜻한다.
C++ 11 이전의 문제
함수 리턴 시 메모리 복사의 문제가 발생한다!
메모리 사용 순서 1. scores 에서 메모리 할당 2. ConvertToPercentage 함수 내 percentages 에서 메모리 할당 -> 1차 복사 3. ConvertToPercentage 함수 리턴 시 임시 메모리 할당 -> 2차 복사
함수의 리턴 값을 변수에 저장할 때(임시값, rvalue), 두 번의 복사가 일어난다! -> 값의 크기가 크면 클 수록 문제는 크다.. -> 최근에는 컴파일러가 이러한 문제가 일어나지 않도록 동작한다.

이동생성자
복사 생성자
복사 생성자를 사용했을 때는 내부적으로 깊은 복사가 일어나 원본과 복사본 모두 메모리를 가지고 있는 것을 볼 수 있다. -> 말 그대로 메모리가 복사된다.

이동 생성자
이동 생성자를 사용했을 때는 다른 개체의 맴버 소유권을 가져오게 된다.
복사 생성자와 달리 메모리 재할당을 하지 않는다.
메모리 재할당을 하지 않기 때문에, 복사 생성자보다 약간 빠를 수 있다.
약간 얕은 복사와 비슷하다. -> 원본의 값을 유지하지 않는다는 점에서 얕은 복사와 다르다.. (원본의 값을 유지하지 않기 때문에, 생성자의 매개변수가 const 가 아니다!)

이동 대입 연산자
이동 생성자와 정말 같은 개념이다.
메모리 복사를 하지 않는다.
얕은 복사와 비슷하게 동작한다.
다른점은 다음과 같다.
생성자는 새로 만들려는 개체의 멤버변수 값을 초기화 하는 과정이라면, 대입 연산자는 이미 개체의 멤버변수 값이 있고 그 값을 초기화하는 과정이다.
때문에, 자신의 멤버변수 중 동적할당이 된 멤버변수가 있다면, 메모리를 수거 한 이후에 초기화해주어야 한다.
자기 자신에 이동 대입연산자를 사용하는 경우 아무런 연산도 필요 없다..

STL 컨테이너용 이동 문법
C++11 이후로 STL 컨테이너에 이동생성자와 이동 대입 연산자가 생김
그래서, 그것들을 위해서 따로 구현할 필요가 없다.
ravalue 최적화에 대한 평가
이동생성자, 이동 대입 연산자에 한정하여 성능이 좋다. (멤버변수 중 동적할당이 이루어지는 경우에 한정) -> 힙 메모리에서 값 복사가 이루어지지 않는 것은 성능이 좋다.
하지만, 포인터 대신 개체 자체를 반환하는 함수에서 rvalue 를 반환하는 것은 실제로 매우 느리다. -> 반환 값 최적화(return value optimization) 최적화를 깨뜨린다.
BEST PRACTICE
기본적으로 개체를 반환하자!
더 빨라진다고 입증된 경우에만 rvalue 를 반환하도록 바꾸자!
Last updated