a = 10;
a = b;
a = b;
L-Value(좌변값) 와 R-Value(우변값) 는 배정자(=) 를 기준으로 생각한다.
' = ' 을 기준으로 왼쪽은 저장되는 곳, 오른쪽은 저장될 값이다.
다시 말하면 L-Value는 저장될 주소값이 되는 것이다.
그렇기 때문에 L-Value 는 기본적으로 const 가 아닌 값이 바뀔수 있는 형태가 되어야 한다.
하지만 R-Value 는 상수던 변수던 상관 없게 된다.
정리하자면

(출처 : http://orz.or.kr/tt/orz/entry/L-Value-R-Value )
이런 표가 나오게 된다.
위에서 말했듯이 배정자(=)를 기준으로 L-Value 와 R-Value 를 생각하게 되는데
또 다른 판정이 있는 경우는
1) 함수의 리턴 값으로 리턴 받는 받는 임시 객체는 R-Value
2) T() 와 같이 명백하게 생성자를 호출해서 리턴 받는 값 역시 R-Value
(출처 : http://cafe.naver.com/ecpp.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=143 )
이다.
다시 말하면 명시적 const 가 아닌 경우이다.
흔히 사용하는 식인
a = foo();
b = new a(); // b 는 포인터값이 아닙니다.
b = new a(); // b 는 포인터값이 아닙니다.
에서 foo()의 리턴과 a()의 리턴(생성자도 결국은 자기자신의 주소값을 리턴하는 겁니다.)은
R-Value 이 된다.
저런 R-Value 의 경우 const & 이 되게 된다.
여기서 클래스설계시 문제가 된다.
대입(=), 복사생성자를 사용시 다른 클래스로 넘겨주기 전에
넘겨주는 쪽에서 값을 바꿔줘야 할때가 있는데 ( 예 : std::auto_ptr )
명시적인 const 값을 넘겨줬을 때는 불가능하게 하는 것이 정상이다.
물론 mutable 로 패스할 수 있겠지만 이것은 const 의 기본개념을 깨게 된다.
하지만 명시적인 const 가 아닌 경우
즉, 위 1), 2) 에서는 정상작동이 되게 해줘야 한다.
그래서 중간계층을 이용해서 const 를 피해가게 한다.
형변환 연산자인 operater 를 이용해서 중간계층으로 바꿔주는데
이것을 R-Value 를 L-Value 로 바꿔준다고 한다.
이 과정을 통해 명시적인 const 를 막아주고 임시변수의 경우는 중간계층을 통해
정상수행될 수 있게 해주는 것이다.
http://cafe.naver.com/ecpp.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=143
에 이 내용들이 다 있으나 어려운 면이 많아서 다시 정리해서 썼다.
Posted by NFIsNOT


