이동 연산은 커스텀 자료형, 즉 유저가 정의한 클래스나 구조체에서 사용하기 위한 기능이다.
기본 자료형에는 이동연산이 정의되어 있지 않다.
기본 자료형(예: int, float, double, 포인터 등)에 대해서는 이동 연산이 필요하지 않습니다. 이유는 다음과 같습니다:
- 단순성: 기본 자료형은 매우 단순한 구조를 가지고 있으며, 값 자체를 복사하는 데 드는 비용이 매우 적습니다. 이동 연산의 이점은 복사가 비싼 객체(예: 대규모 배열, 동적 할당된 메모리 등)에서만 유의미합니다.
- 메모리 관리: 기본 자료형은 복사 시에 새로운 메모리를 할당하거나 할당된 메모리를 관리하는 복잡한 과정이 필요하지 않습니다. 예를 들어, int형 변수의 경우 복사하면 그저 값만 복사하면 됩니다.
- 표준 라이브러리: C++ 표준 라이브러리에서는 기본 자료형에 대해 이동 연산을 정의하지 않습니다. 이는 복사의 비용이 충분히 낮기 때문에 굳이 이동 연산을 사용할 필요가 없기 때문입니다
이동 연산의 목적은 커스텀 자료형들이 다뤄내는 메모리의 크기가 큰데 이때 발생하는 불필요한 복사연산을 줄여서 효율적으로 사용하기 위함이다.
이동 연산의 정의를 보면 이동 연산은 메모리의 주소값을 가져와서 흔히 말하는 소유권을 넘겨주기 때문에 포인터 복사를 수행하는 부하만 가진다.
위의 소스에서도 생성자와 복사 생성자에서는 string_content에 메모리를 할당하는데 이동 생성자에서는 매개변수로 받은 객체의 string_content의 주소를 가져온다.
이후에 매개변수로 받은 객체의 string_content의 주소값을 nullptr로 설정하여 해당 객체와 중복소유를 방지함과 동시에 해당 객체의 소멸 시 메모리가 해제되지 않도록 한다.
좌측값으로 선언된 객체를 통해서 이동생성자나 이동대입연산자를 호출 할 수 없는 문제가 있다. 이동연산은 우측값을 통해서만 호출이 가능하기 때문. 따라서, 이동생성자와 이동대입연산자를 좌측값 객체를 통해서도 호출 할 수 있도록 해주는 것이 std::move 다
위 소스처럼 사용하는 것이고 a는 좌측값으로 선언된 객체지만 std::move를 통해서 우측값으로 캐스팅되어 c에 전달된다.
주의해야할 점은, 주소값 복사를 수행할 수 없는 변수에 대해서는 값복사를 수행해야하므로 이동연산이 항상 저렴하다고 볼 수는 없다.
std::forward는 완벽전달을 위해 사용되는 기능이다.
위의 소스를 참고하여,
main 함수의 const A ca는 템플릿 함수의 매개변수가 T& 혹은 T&&가 아닐 경우 즉, T일 경우에 const가 무시되고 자료형 A가 된다. T&&의 형태는 보편참조 연역형식에 따라서 좌측값은 좌측값으로, 우측값은 우측값으로 형식을 연역하기 때문에 좌측값과 오른값의 형태를 T, T&와는 다르게 모두 제대로 받을 수 있으며 해당 형태를 중간에 발생할 원치않을 형식연역 없이 전달하기 위해서 std::forward<T>를 통해 전달한다.
'C++' 카테고리의 다른 글
__declspec(dllexport) (0) | 2024.06.20 |
---|---|
extern "C" (0) | 2024.06.20 |
HeapAlloc & HeapFree (0) | 2024.05.15 |
기본 클래스와 interface class (0) | 2024.05.01 |
컴파일 타임에 타입을 모르는 경우(C++) (1) | 2024.04.08 |