The main() function code we just saw demonstrates many useful techniques and some controversial behaviors of the auto_ptr smart pointer. The following code creates two instances of auto_ptr, namely ptr1 and ptr2, that wrap two objects of MyClass created in a heap:
auto_ptr<MyClass> ptr1( new MyClass() );
auto_ptr<MyClass> ptr2( new MyClass() );
Next, the following code demonstrates how the methods supported by MyClass can be invoked using auto_ptr:
ptr1->sayHello();
ptr2->sayHello();
Hope you observed the ptr1->sayHello() statement. It will make you believe that the auto_ptr ptr1 object is a pointer, but in reality, ptr1 and ptr2 are just auto_ptr objects created in the stack as local variables. As the auto_ptr class has overloaded the -> pointer operator and the * dereferencing operator, it appears like a pointer. As a matter of fact, all the methods exposed by MyClass can only be accessed using the -> pointer operator, while all the auto_ptr methods can be accessed as you would regularly access a stack object.
The following code demonstrates the internal behavior of the auto_ptr smart pointer, so pay close attention; this is going to be really interesting:
ptr2 = ptr1;
It appears as though the preceding code is a simple assignment statement, but it triggers many activities within auto_ptr. The following activities happen due to the preceding assignment statement:
- The ptr2 smart pointer will give up the ownership of MyClass object 2.
- MyClass object 2 will be destructed as ptr2 has given up its ownership of object 2.
- The ownership of object 1 will be 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 commented line has got some facts to tell you:
// ptr1->sayHello();
As the ptr1 smart pointer has released its ownership of object 1, it is illegal to attempt accessing the sayHello() method. This is because ptr1, in reality, isn't pointing to object 1 anymore, and object 1 is owned by ptr2. It is the responsibility of the ptr2 smart pointer to release the memory utilized by object 1 when ptr2 goes out of scope. If the preceding code is uncommented, it would lead to a core dump.
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. The beauty is all this happens automatically. The auto_ptr smart pointer works hard for us behind the scenes while we are focusing on the problem at hand.
However, due to the following reasons, auto_ptr is deprecated in C++11 onward:
- An auto_ptr object can't be stored in an STL container
- The auto_ptr copy constructor will remove the ownership from the original source, that is, auto_ptr
- The auto_ptr copy assignment operator will remove the ownership from the original source, which is, auto_ptr
- The original intention of copy constructor and assignment operators are violated by auto_ptr as the auto_ptr copy constructor and assignment operators will remove the ownership of the source object from the right-hand side object and assign the ownership to the left-hand side object