You don't need move semantics to have RAII work. If you have a copyable type with a destructor where the cleanup should only happen once, then you already need some kind of refcount to only run the cleanup when the last copy is dropped. Either the refcount is in your own type, or you're wrapping another copyable refcounting type like shared_ptr.
Notice how I said "cleanup-via-destructor" rather than just "destructor", for this reason.
You’re right, but one problem with c++ is that types are copiable by default and copies happen automatically and silently in many situations. So something like this is easy to get wrong.
Notice how I said "cleanup-via-destructor" rather than just "destructor", for this reason.