본문으로 건너뛰기
모던 C++ 심화LESSON 10

이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가

난이도중급 → 심화
예상 시간70분
선수지식이전 강의

10강. 이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가

이번 강의에서 해결할 문제​

std::move를 호출하면 메모리가 즉시 이동한다고 오해하기 쉽습니다. 실제로 std::move는 이동 가능한 값 범주로 캐스팅할 뿐이고, 이후 선택된 이동 생성자나 이동 대입 연산자가 자원을 넘기는 일을 합니다.

학습 목표​

먼저 알아야 할 핵심 개념​

이름이 있고 다시 사용할 수 있는 표현식은 보통 lvalue입니다. 임시값이나 명시적으로 이동 가능한 범주로 바뀐 값은 rvalue 참조 오버로드에 연결될 수 있습니다. 표준 라이브러리 타입의 이동 후 객체는 파괴하거나 새 값을 대입할 수 있는 유효 상태지만 구체 내용은 타입 계약을 확인해야 합니다.

왜 이 문제가 위험한가​

이동 후 문자열이 반드시 빈 문자열이라고 가정하거나, const 객체에 std::move를 붙이면 무조건 이동된다고 생각하면 잘못된 최적화가 됩니다. const T&&에서 자원을 수정해 가져갈 수 없어 복사가 선택될 수 있습니다. 반환값에 무심코 std::move를 붙이면 반환값 최적화를 방해할 가능성도 있습니다.

가장 작은 예제로 시작하기​

move_observer.cpp
#include <iostream>
#include <string>
#include <utility>
#include <vector>

class Buffer {
public:
explicit Buffer(std::string name) : name_{std::move(name)} {}
Buffer(const Buffer& other) : name_{other.name_} { std::cout << "copy\n"; }
Buffer(Buffer&& other) noexcept : name_{std::move(other.name_)} {
std::cout << "move\n";
}
Buffer& operator=(Buffer&& other) noexcept {
name_ = std::move(other.name_);
std::cout << "move assign\n";
return *this;
}
const std::string& name() const { return name_; }
private:
std::string name_;
};

int main() {
Buffer source{"asset"};
std::vector<Buffer> values;
values.push_back(std::move(source));
source = Buffer{"reused"};
std::cout << values.front().name() << ':' << source.name() << '\n';
}

코드 한 줄씩 이해하기​

  1. 복사·이동 생성자 로그가 어떤 경로가 선택됐는지 보여 줍니다.
  2. 이동 생성자는 std::string 멤버를 이동하고 noexcept로 실패하지 않는 계약을 제공합니다.
  3. std::move(source) 자체는 캐스팅이고 push_back이 이동 생성자를 호출합니다.
  4. 이동 직후 source.name() 내용은 가정하지 않습니다.
  5. 새 Buffer를 대입한 뒤 source를 정상적으로 재사용합니다.

실행 결과와 메모리·동작 흐름​

push_back에서 move, 새 값을 대입할 때 move assign, 마지막에 asset:reused가 출력됩니다. values의 원소가 처음 문자열 자원의 새 소유자가 됩니다. 원본은 파괴 가능한 유효 상태로 남고 이동 대입으로 새 값을 받은 뒤 다시 사용됩니다.

단계별 실습​

흔한 실수와 해결 방법​

언제 사용하고 언제 피할까​

더 이상 원본 값이 필요 없고 소유 자원을 넘기는 의미가 분명할 때 이동합니다. 작은 복사 가능 값, 이후 원본이 필요한 값, 컴파일러가 반환 최적화를 할 수 있는 단순 값 반환에는 불필요하게 붙이지 않습니다.

게임 개발 연결​

큰 버퍼나 작업 패킷을 큐에 넘길 때 이동이 유용하지만, 이동 후 원본 상태를 프레임 로직에서 다시 읽지 않도록 책임 경계를 명확히 합니다.

이해 점검 질문 3개​

  1. std::move와 이동 생성자의 역할은 어떻게 다른가요?
  2. const 객체에 std::move를 적용해도 복사가 선택될 수 있는 이유는 무엇인가요?
  3. 이동 후 객체에 새 값을 대입한 뒤 재사용할 수 있는 이유는 무엇인가요?

핵심 요약​

다음 강의 연결​

11강. Rule of Zero·Three·Five에서 직접 자원을 관리하는 클래스가 어떤 특별 멤버 함수를 필요로 하는지 판단합니다.

MINI QUIZ

이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1다음 중 “이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가”의 핵심 요약을 실제 상황에 맞게 적용한 것은 무엇인가요?
  2. 문제 2“이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가”의 작업 기준으로 ‘std::move가 데이터를 이동한다고 설명’을 진단하거나 바로잡은 선택은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

10강. 이동 의미론: std::move는 무엇을 하고 무엇을 하지 않는가 미완료 상태