이부분은 좀처럼 이해가 가질 않아서 여러 문서들을 확인을 하였다. 단순히 R Value 쓰면 좋아요 라는데 왜? 라는 이유가 계속 붙었다. 하지만 이해를 하고 나니 엄청 중요한 내용이라는 생각이 들었다.
무엇보다 이해를 어렵게 한건 선행으로 알아야하는게 다른거에 비해 양이 좀 된다.
먼저 변수 형식은 L Value와 R Value가 있다.
L Value는 수정이 되는 데이터 R Value는 수정이 안되는 데이터 말그대로 임시 데이터이다.
int a = 10;
a : L Value -> 수정될수 있다. ex) a = 5;
10 : R Value -> 수정이 안된다 ex ) 10 =5 ??? error
다음으로 알아야할건 std::move 인데 쉽게 말하면
L Value 데이터 => R Value 데이터
로 변환해주는 함수다. 그리고 std::move 로 넘겨진 데이터는 단순 넘기는것이 아닌 소유권까지 넘기며 기존 L Value엔 빈값이 담기게된다. (const 쓰면 그냥 복사함)
이정도의 정보를 가지고 아래를 보자.
C++에서의 함수 호출 방식은 크게 두가지였다.
Call by Value
Call by Reference
Call by Value는 데이터의 복사가 이루어 지기 때문에 int 타입이나 단순한 데이터는 모르겠지만 큰 Object 파일 같은 경우 복사가 이루어지면 퍼포먼스가 크게 떨어지게 된다.
Call by Reference는 데이터를 참조 하기 떄문에 이런 복사에서 자유로워진다. 하지만 수정을 할수 있기에 수정을 못하도록 const를 붙여서 쓰는것이 권장이 된다.
하지만 두개 다 하나의 문제점이 있는데 아래의 함수를 보자
void Test1(std::string str) // 복사를 한다.
{
std::string strV = str; // 복사를 한다.
}
void Test2(const std::stringt& str) // 복사가 이루어 지지 않는다.
{
std::string strRef = str; // 복사를 한다.
}
int main()
{
std::string tmp = "Test";
Test1(tmp);
Test2(tmp);
}
Call by Value와 Call by Reference 둘다 함수 안에서 Object 를 전송할경우 복사가 이루어진다.
하지만 R Value로 구현하면 얘기는 달라진다.
void Test3(std::string&& str) // 복사 안함
{
//std::string strRE = str; // Error
std::string strRV = std::move(str); // 복사 암함
}
int main()
{
Test3("Test");
}
받는것은 RValue 타입으로 받고 이것을 R Value로 받을수 있게 해주어 복사가 이루어 지지 않게 해준다.
이게 무슨 말인지 어려울것이다. 밑에 그림을 봐주면 그나마 이해가 쉬울것이라 생각된다.
1. 먼저 tmp 변수는 Test 힙데이터를 가르킨다.
2. 함수 호출 후 str은 복사된 Test를 가르킨다.
3. 마지막으로 strV에 str가 가르키는 Test를 복사한다.
1. tmp변수는 Test 데이터를 가르킨다.
2. str참조 변수는 tmp가 가르키는 Test데이터를 가르킨다.
3. strRef는 str이 가르키는 Test데이터를 복사해서 가르킨다.
1. Test라는 임시 데이터를 만든다.
2. str에서 임시데이터인 Test를 가르킨다.
3. strRV에서는 str이 가르키는 Test를 가르킨다.
* std::move에 의해 str이 가르키는 Test의 소유권이 strRV로 넘어가며 str엔 데이터가 없어지게 된다.
'C++ > C++11' 카테고리의 다른 글
C++11 특징 (std::pair, std::tuple) (0) | 2021.03.10 |
---|---|
C++11 특징 (Uniform 초기화) (0) | 2021.03.05 |
C++11 특징 (lambda) (0) | 2021.03.03 |
C++11 특징( ranged for loop) (0) | 2021.03.03 |
C++11 특징 (auto) (0) | 2021.03.02 |