C++11에서 가장가장 핵심적인 부분.
이거 때문에 C++이랑 C++11이랑 속도 차이가 남.
단일식을 넘어서 계속 지속되는 개체
lvalue가 아닌 나머지(임시값, 열거형, 람다, i++ 등)
이런식으로 오른쪽에서 사용할 수 있는 애들을 rvalue라고함.
TestKnight_LValueRef의 인자으,ㅣ Knight& knight가 lvalue이다.
얘는 임시 객체라 rvalue이다.
이런 경우라면 통과함.
오름값 rvalue라 함은
임시적으로 만들어졌다가 곧 소멸된 아이인데
만약 이버젼에서 rvalue를 받을 수 있다면
이렇게 받을 수 있다면 곧 사라질 아이인데
이런식으로 고칠 수 있는 문제가 발생할 수도 있다.
또한 이러한 경우 일반 멤버 함수 사용할 수 없고
이렇게 const가 붙은 함수만을 사용할 수 있다.
이런 오름값 rvalue를 받을 수 있는 새로운 방법이 생김.
참조의 참조가 아니라 오름값을 참조한다는 특별한 의미이다.
rvalue만 받을 수 있음.
lvalue못 받는다.
얘는 원본 자체를 사용할 것인데
마음대로 사용해라~ 왜 => 어차피 삭제할 아이라서...
원본은 더이상 사용하지 않을 것이라는 중요한 힌트가 있는 것이다.
이동 생성자
이런 버젼이 하나 만들어지고
이동 대입 연산자가 만들어진다.
인자로 받아준 knight를 훼손해도된다는 차이점이 생긴다.
(복사대입 연산자와 차이점)
이렇게 원본 훼손이 가능하다.
지금 이게 실행이 되면은 '이동 대입 연산자'가 호출이 된다.
지금 k2를 더이상 유지를 안해도 된다.
k2는 버리는 애라고 힌트를 주는 것이다.
ㅇㅇ.
이거 두개 같다.
move정의 가보면
'&&'이거 있는데 오름값 참조로 바꿨다.
결국 std::move가 뭔가를 이동시켯다라는게 아니라
k3 = static_cast<Knight&&>(k2);
이것처럼 캐스팅을 해주었다는 것이다.
std::move를 이용해서 '얕은 복사'로 모든 것을 다 꺼내서 쓸 수 있다.
성능적인 이점이 높다.
(복사가 빠르다)
왜???
Knight* 녀석을 막 사용하고 그러다보면
누가 이녀석을 관리를 하고 있는지 애매해 진다.
그래서 경우에 따라서 그 포인터가 세상에 딱 하나만 존재해야 한다고 하면은
그녀석을 유니크 포인터로 만들어 줄 수 있다.
그 값을 그대로 복사를 하려고 하면 에러가 난다.
클래스 설계할 떄 복사 delete해놓음.
그런데 이것을 유니크 포인터를 바꾸고 싶을 때
오름값 참조로 바꿀 수가 있다.
이런식으로 하면
uptr2가 uptr의 모든 권한을 다 받고
uptr은 쓰레기 값이 된다.
Knight의 모든게
이렇게 다 이전이 되고
원본 같은 경우 비어있게 된다.