- [Modern C++ 정리] Move 42022년 09월 08일
- starryeye
- 작성자
- 2022.09.08.:59
반응형본격적으로 move 생성자 (이동 생성자)에 대해 알아보자..
Cat 클래스의 정의 및 선언 부이다.
16 line에서 const lvalue reference로 복사(copy) 생성자를 정의 하였다.
rvalue, lvalue 모두 지원된다.
깊은 복사로 구현하였다.
24 line은 이동(move) 생성자이다.
rvalue reference의 파라미터로 정의 되었다.
rvalue가 지원된다. (rvalue를 넣으면 16 line 보다 우선이다.)
특징은..
들어온 임시객체(rvalue)의 모든 값을 얕은 복사 한다.
임시 객체의 포인터 변수 name은 nullptr로 할당하여
이후, 호출 부분에서 임시객체가 파괴 될때, 포인터 변수의 name이 해제 되지 않도록 한다.
위와 같이 rvalue의 값을 변경하기 위해서..
C++11에서 상수성 없이 rvalue를 가리킬수 있는 rvalue reference가 필요했고 도입된 것이다.
foo() 함수와 main() 함수를 알아보자.
foo() 함수는
1. Cat 클래스의 이름있는 객체 c가 생성된다.
2. call by value로 Cat 클래스의 임시 객체가 반환된다.
반환될 때, c가 복사 되어 임시객체가 생성되고 반환된다.
-> 복사 생성자 (const lvalue reference 사용)
3. foo() 함수 블럭이 끝날때, c는 파괴된다.
main() 함수는
51 line에서 이름 있는 객체 c1이 생성된다.
54 line에서 c1을 이용해 c2가 생성된다.
-> 대입 연산자 이지만 초기화 이기 때문에, 생성자 사용됨.
-> lvalue 를 이용한 복사 생성자 -> const lvalue reference 사용된 복사 생성자.
56 line에서는..
foo() 함수 리턴 임시객체를 이용하여 c3가 생성된다.
-> 대입 연산자 이지만 초기화 이기 때문에, 생성자 사용됨.
임시객체는 rvalue이므로 사용된 생성자는 move 생성자이다.
move vs copy
copy 생성자는 파라미터로 lvalue가 사용되어
들어올 때 부터 copy된다..
또한, 내부에서 보통 깊은복사 사용하여..
메모리 할당을 새로 해준다.
하지만, move 생성자는
파라미터로 rvalue가 사용되어..
들어올 때 넣어준 데이터의 주소가 사용되기 때문에
copy되는 작업이 없다.
또한, 내부에서도 보통 얕은 복사를 사용하여,
메모리 할당이 새로 되는 일은 없다.
-> 성능향상
(파라미터 rvalue는 더 이상 사용되지 않음을 보장 할때 사용)
<참고>
copy elision 이라는 기술이 있다.
현재 코드에서는
foo()함수 리턴 시, 임시객체 생성될 때 생성자가 불리지 않고 생략된다.
해당 내용은 추후 따로 포스팅 하겠다..
std::move() 에 대해 알아보자.
기존 main() 함수에
47 line, 49 line을 추가하였다.
47 line..
1. lvalue(c2)를 rvalue로 캐스팅하였다.
2. rvalue로 캐스팅하고 c4를 대입연산자로 넣으려고 시도하였다.
3. 초기화는 대입연산자 대신 생성자를 사용한다.
4. rvalue이므로 move 생성자를 이용하여 생성하였다.
49 line은 47 line과 정확히 동일하다.
따라서, std::move()는 lvalue를 rvalue로 캐스팅 해주는 함수이다.
std::move() 결론..
1. std::move() 자체가 객체의 자원을 이동하는 것은 아니다.
2. 단지, 객체를 rvalue로 캐스팅하는 것이다.
3. 캐스팅의 결과로 move 생성자 호출
4. 결국, 자원을 이동하는 것은 클래스 안에 있는 move 생성자가 한다.
<참고>
어떤 lvalue 객체를 std::move()를 수행하여 rvalue로 캐스팅하여,
lvalue 객체를 생성하는 코드가 있다고 하자..
이때, 해당 클래스에 move 생성자가 없다면..
그냥 복사 생성자를 사용하게 된다.(const Cat& c)
-> 즉, 성능향상은 없지만, 에러는 아니다.
반응형'C++' 카테고리의 다른 글
[Modern C++ 정리] Move 3 (0) 2022.09.08 [Modern C++ 정리] Move 2 (0) 2022.09.08 [Modern C++ 정리] Move 1 (0) 2022.09.07 [Modern C++ 정리] Temporary 6 (0) 2022.09.06 [Modern C++ 정리] Temporary 5 (0) 2022.09.06 다음글이전글이전 글이 없습니다.댓글