Let me preface by saying that I have read some of the many questions already asked regarding move semantics. This question is not about how to use move semantics, it is asking w
Your string example is great. The short string optimization means that short std::string
s do not exist in the free store: instead they exist in automatic storage.
The new
/delete
version means that you force every std::string
into the free store. The move
version only puts large strings into the free store, and small strings stay (and are possibly copied) in automatic storage.
On top of that your pointer version lacks exception safety, as it has non-RAII resource handles. Even if you do not use exceptions, naked pointer resource owners basically forces single exit point control flow to manage cleanup. On top of that, use of naked pointer ownership leads to resource leaks and dangling pointers.
So the naked pointer version is worse in piles of ways.
move
semantics means you can treat complex objects as normal values. You move
when you do not want duplicate state, and copy
otherwise. Nearly normal types that cannot be copied can expose move
only (unique_ptr
), others can optimize for it (shared_ptr
). Data stored in containers, like std::vector
, can now include abnormal types because it is move
aware. The std::vector
of std::vector
goes from ridiculously inefficient and hard to use to easy and fast at the stroke of a standard version.
Pointers place the resource management overhead into the clients, while good C++11 classes handle that problem for you. move
semantics makes this both easier to maintain, and far less error prone.