L value : 한번 호출 후 다시 부를 수 있는 것

R value : 임시적으로 사용하는 값

int a = 10		// a : L-value , 10 : R-value
int b = a		// b : L-value , a  : L-value

string s = "abc"	// s : L-value , "abc" : R-value

 

L-value  를   R-value 바꿔주는 move 함수도 있다.

std::string c = std::move(a);	// L-value 인 a 를 move 를 통해 R-value 로 바꿔준다. (임시 값)

왜 바꿔주는 걸까?

R-value 들은 다시 호출하지 않을 객체들이다.

이렇게 a 를 R-value 로 바꿔주고 c 가 가리키게끔 하면, a 는 해당 값을 c 에게 뺏기게 된다. (ownership 을 넘겨준다)

c 가 힙에 있던 값을 가리키고, a 는 nullptr 혹은 사이즈가 0인 새로운 공간을 가리키게 된다.

일반적으로는 새로운 힙을 가리키지만, string 의 최적화 때문에 size 가 짧아 그냥 스택을 가리킨다고 하는 것이 정확하다.

(저렇게 move 를 통해 R-value 로 변경된 a 를 이후에 사용하지 않아야 한다는 보장이 있어야 한다)

string a = "bconfiden2"			// 스택 a -> 힙 "bconfiden2"
string& b = a;				// 스택 b -> 힙 "bconfiden2" (a 와 같은 메모리)	
string c = move(b);			// a 와 b 를 R-value 로 바꾸고 해당 "bconfiden2" 를 c 가 소유
							// 이후 a 와 b 는 쓰레기 ~!~!

다만 const 객체는 move 하여 넣더라도 복사가 일어난다.

 

 

두 레퍼런스의 차이는 다음과 같다. 사실 그림을 그려서 올리는게 훨씬 이해도 잘되는데,, 아이패드 사고 싶다.

void value(string s)		// 스택에 있는 s 가 힙에 있는 새롭게 복사된 "test" 를 가리킴
{
    string temp = s;		// temp 역시 똑같이 복사됨
}

void L_reference(string& s)	// 스택에 있는 s 가 a 와 똑같은 힙 공간을 가리킴
{
    string temp = s;		// temp 는 복사가 된다!
}

void R_reference(string&& s) 	// s 가 힙에 있던 임시 객체 "test" 를 가리킴
{
    string temp = s;		// temp 가 스택에 생기면서 s 가 가리키던 값을 힙에 복사해서 가리킴
    string temp = std::move(s)  // 이렇게 R-value 로 바꿔줄 경우 복사가 일어나지 않는다!
}

int main(void)
{
    string a = "test";		// 스택에 있는 a 가 힙에 있는 "test" 를 가리킴
    value(a);				
    L_reference(a);			
    R_reference("test");	// 애초에 넘어가는 "test" 는 임시 객체
    R_reference(a); 		// wrong! 레퍼런스를 R-value를 받기 때문에 L-value를 넘겨줄 수 없다
    R_reference(std::move(a))	// 이렇게 바꿔 줄 수 있겠다.
}

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

[C++] 얼리 리턴?  (0) 2020.07.10
[C++] 배열 형식의 인수  (0) 2020.06.30
[C++] const 포인터와 const 로의 포인터?  (0) 2020.06.29
[C++] 키워드 static  (0) 2020.05.26
[C++] list 를 쓸까?  (0) 2020.05.22

+ Recent posts