상세 컨텐츠

본문 제목

lvalue와 rvalue, 그리고 참조자

프로그래밍

by 경밤 2022. 7. 23. 17:05

본문

반응형

왜 참조자를 사용하는가?

객체를 복사하지 않고 주소만 가져와 참조하기 위해서다.

lvalue와 rvalue의 정의

lvalue는 left-value, 또는 locator-value로 불린다. 왜냐하면 메모리 주소를 얻을 수 있기 때문이고, 값을 할당받을 수 있는 등호 왼쪽 편에 있는 것이기 때문이다. rvalue는 right-value다. 값 자체를 말한다. 등호에서 오른쪽에 위치하면 그것을 rvalue라고 볼 수 있다. 하지만 늘 lvalue와 rvalue가 고정되어 있는 것은 아니다.

int a = 10 // a는 lvalue, 10은 rvalue
int b = a // b는 lvalue, a는 rvalue

위 과정에서 rvalue로써 사용된 a는 컴파일 타임에 10으로 치환된다.

lvalue 참조자

int v = 10
int & a = v;

a는 lvalue 참조자로써, 여기서 v는 rvalue가 되지 않는다. 왜냐하면 a는 lvalue 로써 역할을 할 것을 받기 때문이다. 그러니까, a=v에서 v는 10이 아니라는 것 이다.

rvalue 참조자

가령 함수 f의 매개변수로 const& 을 이용해서 가져오면 방대한 크기의 매개변수를 굳이 복사하지 않고 주소만 가져오게 된다. 추가로 const를 통해 바꾸지 않겠다는 규약도 했다. 하지만 만약, 매개변수로 받은 객체 주소를 따라가 더 이상 그 값이 필요가 없다면? 즉, 값을 완전히 옮겨야하는 상황이라면 rvalue 참조자, &&를 사용한다.

void f(int const & a);

위 경우 임시 객체(100, "str", 'c' ...)도 받을 수 있고, 일반적인 변수 사용하듯이 넘겨서 사용할 수 있다. 하지만 넘겨받은 값을 조정하지는 못한다. 왜냐하면 rvalue를 받기 위해 const를 붙였기 때문이다.

void f(int&& a);

위 경우는 move나 forward 메소드를 사용하여 a의 값을 얻고 a를 없앨 수 있다. Rust에서 말하는 소유권 이전과 같은 개념이다. 이때 임시 객체도 받을 수 있다. 왜냐하면 임시 객체도 특정할 순 없지만 어느 메모리에 저장된 것 이기 때문이다. 

반응형

관련글 더보기