C++ Shallow vs Deep Copy & Move Semantics [#33-2]

C++ Shallow vs Deep Copy & Move Semantics [#33-2]

이 글의 핵심

Explain ownership, avoid double-free, and use move to eliminate redundant allocations in hot paths.

Introduction: interview answers for move semantics

Why moves exist

Returning large vectors, pushing into containers, and transferring unique_ptr should not copy huge buffers. Move transfers ownership of resources in O(1) time for many types—like moving furniture to a new apartment instead of buying duplicates: the destination takes the beds and tables; the old place leaves them empty but valid to tear down.

You will cover: shallow vs deep copy, Rule of Three/Five, rvalue/lvalue, std::move, std::forward, mistakes (RVO, noexcept move), benchmarks, production patterns.


Shallow vs deep

  • Shallow: duplicate pointer values → shared heap object → double free risk.
  • Deep: allocate new buffer and copy contents → independent lifetimes.

Picture two notecards with the same street address (shallow): both point at one house. Deep copy builds a second house and copies the furniture inside.


Rule of Three / Five

If you customize destructor, copy ctor, or copy assign, think through all five (add move ctor + move assign) for resource-owning types.


Move semantics

std::move is a cast to rvalue; moved-from objects remain valid but unspecified—do not rely on their values afterward.


Perfect forwarding

template<class T> void f(T&& x); with std::forward<T>(x) preserves value category for wrapper factories.


Pitfalls

  • return std::move(local) harms RVO.
  • Move-after-use bugs.
  • Missing noexcept on cheap moves → vector reallocation copies elements.

Production patterns

Factories returning unique_ptr, emplace_back, optional, PIMPL + move.

Keywords

move semantics, Rule of Five, rvalue reference, std::move, copy elision