Unique ownership without move semantics std::auto_ptr

suggest change

NOTE: std::auto_ptr has been deprecated in C++11 and will be removed in C++17. You should only use this if you are forced to use C++03 or earlier and are willing to be careful. It is recommended to move to unique_ptr in combination with std::move to replace std::auto_ptr behavior.

Before we had std::unique_ptr, before we had move semantics, we had std::auto_ptr. std::auto_ptr provides unique ownership but transfers ownership upon copy.

As with all smart pointers, std::auto_ptr automatically cleans up resources (see RAII):

{
    std::auto_ptr<int> p(new int(42));
    std::cout << *p;
} // p is deleted here, no memory leaked

but allows only one owner:

std::auto_ptr<X> px = ...;
std::auto_ptr<X> py = px; 
  // px is now empty

This allows to use std::auto_ptr to keep ownership explicit and unique at the danger of losing ownership unintended:

void f(std::auto_ptr<X> ) {
    // assumes ownership of X
    // deletes it at end of scope
};

std::auto_ptr<X> px = ...;
f(px); // f acquires ownership of underlying X
       // px is now empty
px->foo(); // NPE!
// px.~auto_ptr() does NOT delete

The transfer of ownership happened in the “copy” constructor. auto_ptr’s copy constructor and copy assignment operator take their operands by non-const reference so that they could be modified. An example implementation might be:

template <typename T>
class auto_ptr {
    T* ptr;
public:
    auto_ptr(auto_ptr& rhs)
    : ptr(rhs.release())
    { }

    auto_ptr& operator=(auto_ptr& rhs) {
        reset(rhs.release());
        return *this;
    }

    T* release() {
        T* tmp = ptr;
        ptr = nullptr;
        return tmp;
    }

    void reset(T* tmp = nullptr) {
        if (ptr != tmp) {
            delete ptr;
            ptr = tmp;
        }
    }

    /* other functions ... */
};

This breaks copy semantics, which require that copying an object leaves you with two equivalent versions of it. For any copyable type, T, I should be able to write:

T a = ...;
T b(a);
assert(b == a);

But for auto_ptr, this is not the case. As a result, it is not safe to put auto_ptrs in containers.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Smart pointers:
* Syntax
* Unique ownership without move semantics std::auto_ptr

Table Of Contents
8 Arrays
11 Loops
39 Streams
50 Smart pointers
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype