Programming/c++

[c++] std::move

owls 2023. 10. 20. 14:58
728x90

1. 함수 원형

move 할당 연산자를 호출하는 move 생성자

// Move constructor.
MemoryBlock(MemoryBlock&& other) noexcept
   : _data(nullptr)
   , _length(0)
{
   *this = std::move(other);
}
// C++ 14 이전에는 constexpr 아님!
template <class T>
constexpr typename std::remove_reference<T>::type&& move(T&& t) noexcept;

 

2. std::move

move 할당 연산자

 

메모리, 파일 핸들 및 소켓과 같은 리소스를 해제하여 리소스 누수를 방지할 수 있습니다.

 

std::move함수는 lvalue를 rvalue로 변환합니다.

std::move된 객체를 함수에 전달한다면, 우측값 레퍼런스를 인자로 받는 함수(이동 생성자, 이동 대입 연산자, vector의 push_back 함수 등등) 가 오버로딩 되어서 선택됩니다. 

참고로 우측값 래퍼런스 자체는 rvalue가 아니라 lvalue이기 때문에 이동 생성자나 이동 대입 연산자 내부에서 std::move를 호출하는 경우가 많습니다.

 

예외

유일한 예외적인 상황은 함수 인자가 템플릿 인자의 우측값 레퍼런스인 경우입니다. (Universal Reference)

이 경우 std::forward를 사용해야합니다.

 

주의

이미 이동되서 껍데기만 남은 객체를 접근하며 안된다.

 

3.예제

	string str = "example~";
	
	vector<string> vec;
	vec.push_back(move(str));

	cout << str << "\n";	//
	
	cout << vec[0] << "\n"; // example~

str 객체는 vec로 이동되어서 빈 값으로 나온다.

 

	string str = "example~";
	
	vector<string> vec;

	//push_back(const T&)가 오버로딩 되어서 문자열의 복사가 발생한다.
	vec.push_back(str);

	cout << "After copy, str is [ " << str << " ]\n";  

	//push_back(T&&) 가 오버로딩 되서 문자열의 복사 없이 그대로 전달된다.
	vec.push_back(move(str));

	//일반적으로 이동된 객체를 접근하는 것은 안되지만 c++ string의 경우 
	//비어있음이 보장된다.
	cout << "After move, str is [ " << str << "]\n"; 
	
	cout << "The contents of the vector are [ " << vec[0] << " ] , [ " << vec[1] << " ]\n";
After copy, str is [ example~ ]
After move, str is [ ]
The contents of the vector are [ example~ ] , [ example~ ]

 

 

 

참고 레퍼런스

https://learn.microsoft.com/ko-kr/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=msvc-170

https://modoocode.com/301

 

728x90