LValue란
LeftValue, 단일 표현식을 넘어가도 존재하는 값을 의미한다. (영속성)
예를들어
int i = 0;
char* Name = "홍길동";
++i;
위에서 볼드체로 된 값들은 문장이 넘어가도 존재한다.
RValue란
RightValue, 단일 표현식이 넘어가면 없어지는 값을 의미한다. (비영속성)
예를들어
int a = 10;
int b = 20;
char* Name = "홍길동";
int c = a + b;
c++;
위에서 붉은색 글씨로 된 값들은 그 당시에만 있는 임시값이다.
다른 것들은 쉽게 이해가 된다. 하지만 ++i와 c++는 쉽사리 이해 되질 않는다.
차근차근 알아보자 ++i의 경우에는 연산자오버로딩을 해보면
1 2 3 4 5 6 7 | //point 클래스의 단항연산자 오버로딩(전위) Point& Point::operator++() { ++m_fX; ++m_fY; return *this; } | cs |
이렇게 자기자신을 리턴한다. 이는 영속한 데이터이다. 하지만 c++의 경우 연산자오버로딩에서 보면
1 2 3 4 5 6 7 | //point 클래스의 단항연산자 오버로딩(후위) Point Point::operator++(int) { Point temp = *this; ++(*this); return temp; } | cs |
이렇게 복사본을 리턴한다. 때문에 연산후에도 값이 그대로이며 다음식에서 ++되는 것을 알수있다.
또한 복사본이기 때문에 비영속적이다.
이것이 ++i가 LValue이고 c++가 RValue인 이유라 할 수 있다.
위의 내용이 어렵다면 단순히 해당 식에서 주소를 알아낼 수 있다면 lvalue 불가능하다면 rvalue라 할수도 있다. 예를들어
&i는 가능하지만 &(a + b)는 불가능하다.
서론이 길었는데 원래 포스트의 주제는 RValue를 참조하는 방법에 관한 것이었음으로 이제 본론으로 들어가겠다. 예를 들어
Print(const char& a) //알파벳 하나를 넘겨받아서 출력함
이라는 함수가 있다. 잠시 설명을 하자면 a는 레퍼런스로 매개변수를 넘겨받는다.
레퍼런스이니 당연히 메모리가 할당되지 않으며 변수에 별명을 붙이는 형식이므로 마치 포인터처럼 사용이 가능하다.(값 복사 없이 참조가 가능하다는 뜻)
또한 const로 선언되어 있기에 값을 변경할 수 없다.
즉 const든 non_const든 영속적인 LValue가 저장 가능하다.
결과적으로 a로 넘어오는 파라미터 값이 무엇이든 char형 변수일때 출력이 가능하다.
하지만 위의 함수는 print('a');와 같이 RValue를 파라미터로 호출할 수 없다.
(영속적인 데이터만 저장가능한 변수이기에 파라미터로 넘겨 받을 수 없다.)
때문에 RValue를 저장할 수 있는 레퍼런스가 필요하며 그것이 바로 && 이다.
print(const char&& a);
이와 같이 정의하면 const든 non_const든 비영속적인 RValue가 저장가능하다.
때문에 print('a');와 같은 호출이가능하다.
'All > C++' 카테고리의 다른 글
자주 사용하는 STL function (0) | 2016.11.28 |
---|---|
operator new / operator delete (0) | 2016.03.14 |
메모리 누수 검사 (0) | 2015.12.29 |
가변인자 로그 출력함수 (0) | 2015.12.29 |
문장줄이기 (0) | 2015.12.28 |