Without move semantics, these problems were usually avoided by allocating via a pointer, and passing around the pointer instead of the actual class. In this case, we utilize an old-fashioned raw pointer for clarity, although some sort of smart pointer is probably the most used case (such as shared_ptr, unique_ptr, or the old, deprecated auto_ptr):
auto make_buffer() -> Buffer* { auto buffer = new Buffer({2.0, 4.0, 6.0, 8.0}); return buffer; } // The actual Buffer object isn't copied, just the pointer auto buffer = make_buffer(); // buffer is Buffer*
This has several disadvantages:
- The advantage of value semantics in C++ is lost: the programmer is not relieved from handling pointers manually
- The code ...