거의 알고리즘 일기장

Lvalue와 Rvalue 본문

c++ 문법

Lvalue와 Rvalue

건우권 2020. 4. 7. 15:29

1. Lvalue와 Rvalue 

 

 Lvalue와 Rvalue가 무엇일까?

 

 여러 기준으로 살펴보겠다.

 1) 대입연산자 기준으로 왼쪽이 Lvalue, 오른쪽이 Rvalue

 2) 주소값의 유무

 

 

 1) 대입연산자 기준으로 왼쪽이 Lvalue, 오른쪽이 Rvalue

int a = 1;
int b = 1;

  이렇게만 보면 위의 말이 성립한다. 하지만

int a = 1;
//???
int b = a;

  이때는 1)의 기준이 성립하질 않는다.

 

 

 그러면 이번에는 2) 주소값의 유무로 판단해보자.

int a = 1;
int b = 2;
cout << &a << endl;//가능
cout << &b << endl;//가능
cout << &1 << endl;//불가능
cout << &(a+b) <<endl; //불가능
cout << &(a +1) <<endl; //불가능

 어느정도 성립하는것으로 보인다.

 

 하지만

class a
{
public:
	int v;
	a(int v_in):v(v_in)
	{}
};

int main()
{
	a a1(1);
	
	cout << &a1 << endl;//가능
	cout << &(a(5)) << endl;//가능
	cout << &(a(6)) << endl;//가능
	cout << &(a(5)) << endl;//가능
}

 여기서의 a(5), a(6) 등의 임시객체는 Lvalue가 아닌데도 주소값을 가지고 있다.

 

 그래서 지금까지의 실험을 봤을때는 이렇게 정의할수있다. ( 모든게 성립하진 않을수있음 )

 1) Lvalue는 메모리공간을 가지는 객체를 참조하는 표현식, 단일표현식 이후에도 살아있음.

 2) Rvalue는 Lvalue가 아닌 모든것, 임시적으로 표현이 끝나면 사라짐

 ( 메모리공간을 가지는 객체를 나타낼 필요가 없는 표현식 )

 이렇게 생각하면 편하다.

 


 

2. Lvalue와 Rvalue의 참조

 Lvalue는 알다시피 &을 하나 이름앞에 써서 참조한다.

 Rvalue는 Lvalue에서 &가 하나 더 추가된 (형 && 이름)이렇게 참조한다.

 밑에는 그 예시들이다.

#include <iostream>

using namespace std;

int getReslut()
{
	return 100;
}

void doSomething(int& lref)
{
	cout << "L-VALUE REF" << endl;
}

void doSomething(int&& rref)
{
	cout << "R-VALUE REF" << endl;
}

int main()
{
	int x = 5;
	int y = getReslut();
	const int cx = 6;
	const int cy = getReslut();

	//1. L -value references ( 일반적으로 쓰던 레퍼런스 )

	int& lr1 = x; // modifiable L -value;
	//int &lr2 = cx
	//int &lr3 = 5; // 둘다 안됨

	const int& lr4 = x;
	const int& lr5 = cx;
	const int& lr6 = 5;// 됨

	//2. R - value reference ( R value만 가능 )

	//int&& rr1 = x;
	//int&& rr2 = cx;
	int&& rr3 = 5;
	
	//const int&& rr4 = x;
	//const int&& rr5 = cx;
	int&& rr6 = 5;

	//값을 바꿀수 있다. 왜 이런 문법이 있는걸까?
	cout << rr3 << endl;
	rr3 = 10;
	cout << rr3 << endl;

	doSomething(x);
	doSomething(5);
	doSomething(getReslut());

	return 0;
}

 


 

3. Rvalue 참조의 존재 이유

 

 솔직히 Rvalue 참조는 쓸데 없는것처럼 보인다. 하지만, 이것도 존재하는 이유가 있는데

 이게 존재하는 이유는 내가 공부한바로는 객체간의 복사시간을 줄이기 위해서 주로 사용하는것 같다. 

 예를들어 a = b를 하는데 깊은 복사가 일어난다고 하면, 아마 시간이 오래걸릴것이다. 이때 b를 a =b이후에 사용하지 않을경우 b의 권한을 a에 이동시키면 ( a에 b를 얕은 복사하고 b는 nullptr로 초기화 ) 불필요한 복사, 소멸을 하지않게 되어 시간이 획기적으로 줄어든다.

 뒤에 나오는 이동의 개념, 이동생성자등을 공부하면 확실히 알수있다.

 


 

4. 후기

 

다 쓰고 보니 글이 두서가 없다. ㅠ 

오늘 공부하고 바로 글을 쓰는거라 틀린 부분이 있을수도 있는데 만약 틀린 부분이 있다면 다시 포스팅 하겠다.

 

이 포스트는 홍정모의 따라하며 배우는 C++수업을 듣고 참고해서 개인공부용으로 작성하였습니다.

미숙해서 틀린부분이 있을수도 있는데 말해주시면 수정하겠습니다.

반응형
Comments