본문 바로가기
programing/C++

[Modern C++] RValue Reference

by RedWiz 2016. 12. 29.

- C++98/03에서는 추상화와 효율성을 같이 가려가려다 불필요한 복사가 만들어짐

> ex. vector에서 재할당, string객체 간 결함


- 불필요한 복사를 방지하는 기능 : RValue Reference (우측 값 참조)


cf. 좌측 값, 우측 값

> 좌측값 : *ptr, ptr[index], ++x

> 우측값 : 식이 끝나는 시점에서 사라져 버리는 임시 값, 상수, x+y, std::string("C++")

, (&로 받는) 주소값(상수)


- LValue Reference

> '&'를 사용한 참조

cf. 주소값은 변수에 들어있는 값만 참조를 이용할 수 있다.



- RValue Reference

>'&&'를 사용한 참조


int nCount;

int& lrefValue1 = nCount;    ---- 문제 없음

int& lrefValue2 = 10;    ---------- 에러

int&& rrefValue1 = 10;    -------- 문제 없음

int&& rrefValue2 = nCount;    --- 에러


- Move sementics

> move 생성자, move 대입 연산자가 생김

* move 생성자

CClass(CClass&& rValue)

: Name(new char[ rValue.NameLen]), NameLen(rValue.NameLen)

{

quest.Name = NULL;

quest.NameLen = 0;

}

* move 대입 연산자

CClass& operator=(CClass&& rValue)

{

if(this != &rValue)

{

delete Name;

Name = quest.Name;

NameLen = quest.NameLen;

quest.Name = NULL;

quest.NameLen = 0;

}

return *this;

}


> move 생성자와 move 대입 연산자는 &&를 사용

> 객체를 복사가 아니고 이동 시킬 수 있다.

> move 생성자, move 연산자는 암묵적으로는 만들어 지지 않으며 복사 생성자와 대입 연산자보다 우선 순위가 낮다.

> STL에서도 적용되어서 vector의 크기를 재 할당시 복사가 일어나지 않고 이동이 일어남


- Move로 인한 성능 향상

> 인자를 복사하지 않고 주소를 대입한 것이므로 이동을 이용하여 복사보다 성능이 더 좋음

> 또한 메모리 이동 후에 객체가 사라지더라도 메모리 파괴가 일어나지 않도록 인자로 넘겨 받은 객체에 NULL을 대입


- std::move

> 좌측값(LValue)을 우측값(RValue)으로 타입 캐스팅하기 위해 제공하는 함수


- 우측 값 참조 사용시 주의할 점

> std::move()를 사용한 후 인자로 사용한 변수는의 값은 유효하지 않다.


- 우측 값 참조와 좌측 값 참조는 타입이 다르므로 함수 오버로드를 적용할 수 있다.


- 우측 값은 임시 값이지만 우측 값 참조는 임시 값이 아니다.

> 우측 값 참조는 우측 값 참조로 초기화 할 수 없다.

int LValue1;

int&& RValueRef1 = LValue1;    // Error, 좌측값

int&& RValueRef2 = std::move(LValue1);    // OK, 우측값로 초기화

int&& RValueRef3 = RValueRef2;    // Error, 우측값참조로 초기화


- perfect forwarding

> 좌측값이 우측 값이 되어 우측 값 참조로 사용되면 그 좌측 값은 보증할 수 없음

> 템플릿 프로그래밍에서 인자 추론을 하는데, 인자 추론을 하면서 좌측 값과 우측 값을 구분 못하여 사용한 함수가 원하는 대로 호출 못 할 수 있음

> std::move()를 이용하여도 좌측 값을 전달하려고 해도 우측 값 참조로 사용됨

> std::forward() : 우측 값은 우측 값으로, 좌측 값은 좌측 값으로 캐스팅


'programing > C++' 카테고리의 다른 글

인라인 함수와 템플릿  (0) 2017.01.25
음성 채팅 구현  (0) 2017.01.20
exit(), assert(), 에러처리  (0) 2016.12.27
형변환 연산자 오버로딩  (0) 2016.12.06
explicit  (0) 2016.12.05