프로그래밍/C++

[ C++]r-value

FORHAPPy 2021. 9. 19. 01:45

C++의 모든 값은 r-value 아니면 l-value 이다.

l-value 식의 표현이 지속성을 가진다.
우변 좌변 다 사용 가능하다.
메모리상에 저장되어있다.
즉, 메모리상에 어떤값이 저장되어있을 경우에는 거기에 대입을 할 수 있다.!!
r-value 지속성을 가지지 않는 임시적인 값들을 말한다.
좌변에만 사용가능 하다.

그동안 사용해온 레퍼런스 변수는 변수에 별칭을 지정하는것이었다.

이는 &연산자를 사용하여 원본값을 변화시킬 수 있다.

이것이 l-value reference 이다.

 


<r-value >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
 
 
int c = a * b;  
a* b = 42;  
 
      
int&  f();        --> int& 을 리턴하는 함수 (아직 잘 모르는 부분.)
f() = 42;         --> f() 는 좌측값
int* p1 = &f();   --> &foo() 를 할 수 있다. l-value이기 떄문에
 
 
int f(); { return 5; }-> int형(정수)형을 리턴하는 함수
int j = 0;
= f();             -->f()는 r-value 이다.
f() = j;             -->따라서 이건 불가능 (리턴값을 바꾸진 못한다.)
int* p2 = &foobar(); -->주솟값을 참조하는거도 불가능
 
cs

메모리상에 어떤 값이 저장되어있을 경우에는 거기에 대입을 할 수 있다. (l-value)

하지만 int f(); { return 5; }  처럼 리턴값이 있는 int형 함수는 l-value가 아니다.

리턴값 자체는 임시객체이고 메모리상에 저장은 되어있지만 우리가 return값을 다른 값으로 바꿀 수 없다.

이는 r-value이기 때문이다.

r-value는 값자체를 수정할 수 없고 대입을 할 수 가 없기 때문에 r-value 인 것이다.

따라서 return을 하는 함수 즉 임시객체는  r-value이다.!!

 

 


<클래스를 반환타입으로 가지는 함수>

 

String getName()
{
String res("hello world");.
return res; 
}


<a는 getName의 return값을 받는 변수 a>

 

void main()

{

a = getName();

}

 

  1. 직관적으로 보았을때 getname()에서 a로 한 번의 깊은 복사가 일어 난다고 예상을 할 수 있다.
  2. 그러나 출력해본 결과 두 번의 깊은 복사가 일어 났다.
  3. 복사생성자가 호출이 되고, 대입연산자가 호출이 되면서 깊은 복사는 두번 일어 났다.
  4. getName()은 소멸되면서 return 값을 반환을 한다.  반환과 동시에 함수가 소멸이 되기 떄문에 a로 바로 대입되는 것이 아닌 임시로 다른곳에 저장이 된다. 그러면서 복사생성자가 한번 더 호출이 된다.
  5. 동적할당이 두번이나 진행되면서 불필요한 메모리들이 낭비 되고 있고 효율이 떨어진다.
  6. 따라서 이런 깊은 복사의 문제점을 해결하기 위해 얕은 복사를 해주는 방법을 사용한다.

 

r-value의 참조 형태는 다음과 같다. String &&r = getName() 

r은 r-value 만을 참조할 수 있다. l-value는 참조 할 수 없다.

getName() 얘가 리턴하는건 임시객체인 r-value이다.

r value인 getName()은 표현식 이후에 어디에서도 참조할 수 없는 값이고, 변환을 해도 바뀌지 않는다.

그래서 깊은 복사가 아닌 얕은 복사를 해도 안전하다.

'프로그래밍 > C++' 카테고리의 다른 글

[C++]이동시멘틱_2  (0) 2021.09.22
[C++]이동시멘틱_1  (0) 2021.09.21
[C++]동적할당 복사생성자(요약정리)  (0) 2021.09.17
[C++]포인터  (0) 2021.09.16
[C++]오버로딩  (0) 2021.09.15