It is important to note the differences in the main() function, between auto_ptr and unique_ptr. Let's check out the main() function, as illustrated in the following code. This code creates two instances of unique_ptr, namely ptr1 and ptr2, that wrap two objects of MyClass created in the heap:
unique_ptr<MyClass> ptr1( new MyClass() );
unique_ptr<MyClass> ptr2( new MyClass() );
Next, the following code demonstrates how the methods supported by MyClass can be invoked using unique_ptr:
ptr1->sayHello();
ptr2->sayHello();
Just like auto_ptr, the unique_ptr smart pointers ptr1 object has overloaded the -> pointer operator and the * dereferencing operator; hence, it appears like a pointer.
The following code demonstrates unique_ptr doesn't support the assignment of one unique_ptr instance to another, and ownership transfer can only be achieved with the std::move() function:
ptr2 = std::move(ptr1);
The move function triggers the following activities:
- The ptr2 smart pointer gives up the ownership of the MyClass object 2
- MyClass object 2 is destructed as ptr2 gives up its ownership of object 2
- The ownership of object 1 is transferred to ptr2
- At this point, ptr1 is neither pointing to object 1, nor it is responsible for managing the memory used by object 1
The following code, if uncommented, will lead to a core dump:
// ptr1->sayHello();
Finally, the following code lets us invoke the sayHello() method on object 1 using the ptr2 smart pointer:
ptr2->sayHello();
return 0;
The return statement we just saw will initiate the stack unwinding process in the main() function. This will end up invoking the destructor of ptr2, which in turn will deallocate the memory utilized by object 1. Note that unique_ptr objects could be stored in STL containers, unlike auto_ptr objects.