프로그래밍C++ 백엔드 개발자

C++에서 'move semantics'란 무엇이며 어떻게 작동합니까? 언제 std::move와 std::forward를 사용해야 합니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

Move semantics는 C++의 메커니즘으로, 객체 간에 자원을 복사하는 대신 효율적으로 이동할 수 있게 해줍니다. C++11의 등장으로 이동 생성자와 할당 연산자가 도입되어 객체가 자원을 다른 객체로 이동할 수 있게 하여 복사 비용을 절감합니다.

std::move는 전달된 객체를 rvalue 참조로 변환하여 자원을 안전하게 이동할 수 있음을 나타냅니다. std::forward는 템플릿에서 더 전달할 때 값의 유형 (lvalue/rvalue)을 유지하는 데 사용됩니다.

코드 예제:

#include <string> #include <vector> #include <iostream> std::vector<std::string> getNames() { std::vector<std::string> v = {"Alice", "Bob", "Charlie"}; return v; // 여기서 move semantics가 작동합니다 } int main() { std::vector<std::string> names = getNames(); // 여기서 getNames()의 내용이 불필요한 복사 없이 이동됩니다 }

속임수 질문.

std::move와 이동 생성자의 차이는 무엇입니까? std::move를 쓰면 객체가 항상 이동됩니까?

답변: std::move는 단순히 rvalue 참조로 캐스팅할 뿐이며, 스스로 이동을 수행하지 않습니다. 이동 연산은 실제로 이동 생성자/연산자가 구현되어 있을 때만 발생합니다. 그렇지 않으면 복사가 발생합니다.

struct A { A() = default; // 이동 생성자가 없음 A(const A&) { std::cout << "복사! "; } }; A a1; A a2 = std::move(a1); // 복사가 호출되며 이동되지 않음

이야기

  • 한 금융 시스템에서 문자열 작업을 최적화하기 위해 복사를 std::move로 대체했지만 구조체에 구현된 이동 생성자가 없었습니다. 복사는 여전히 발생하고 성능이 향상되지 않아 코드의 속도 향상에 대한 잘못된 확신이 생겼습니다.

이야기

  • 개발자가 이동 후에도 계속 사용했던 변수에 대해 std::move()를 수행했습니다. 데이터가 일관성이 없는 상태가 되어 애플리케이션이 주기적으로 충돌했습니다.

이야기

  • 서버 라이브러리 코드에서 임시 객체를 const 참조로 받아들이고 나중에 std::move()를 시도하여 이동하기를 기대했습니다. 그 결과, 복사가 발생하고 비효율적인 작업과 큰 부하에서 지연이 증가했습니다.