- 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 |