The unique_ptr smart pointer works in exactly the same way as auto_ptr, except that unique_ptr addresses the issues introduced by auto_ptr. Hence, unique_ptr is a replacement of auto_ptr, starting from C++11. The unique_ptr smart pointer allows only one smart pointer to exclusively own a heap-allocated object. The ownership transfer from one unique_ptr instance to another can be done only via the std::move() function.
Hence, let's refactor our previous example to make use of unique_ptr in place of auto_ptr.
The refactored code sample is as follows:
#include <iostream>
#include <string>
#include <memory>
#include <sstream>
using namespace std;
class MyClass {
private:
static int count;
string name;
public:
MyClass() {
ostringstream stringStream(ostringstream::ate);
stringStream << "Object";
stringStream << ++count;
name = stringStream.str();
cout << "\nMyClass Default constructor - " << name << endl;
}
~MyClass() {
cout << "\nMyClass destructor - " << name << endl;
}
MyClass ( const MyClass &objectBeingCopied ) {
cout << "\nMyClass copy constructor" << endl;
}
MyClass& operator = ( const MyClass &objectBeingAssigned ) {
cout << "\nMyClass assignment operator" << endl;
}
void sayHello( ) {
cout << "\nHello from MyClass" << endl;
}
};
int MyClass::count = 0;
int main ( ) {
unique_ptr<MyClass> ptr1( new MyClass() );
unique_ptr<MyClass> ptr2( new MyClass() );
ptr1->sayHello();
ptr2->sayHello();
//At this point the below stuffs happen
//1. ptr2 smart pointer has given up ownership of MyClass Object 2
//2. MyClass Object 2 will be destructed as ptr2 has given up its
// ownership on Object 2
//3. Ownership of Object 1 will be transferred to ptr2
ptr2 = move( ptr1 );
//The line below if uncommented will result in core dump as ptr1
//has given up its ownership on Object 1 and the ownership of
//Object 1 is transferred to ptr2.
// ptr1->sayHello();
ptr2->sayHello();
return 0;
}
The output of the preceding program is as follows:
g++ main.cpp -std=c++17
./a.out
MyClass Default constructor - Object1
MyClass Default constructor - Object2
MyClass destructor - Object2
MyClass destructor - Object1
In the preceding output, you can notice the compiler doesn't report any warning and the output of the program is the same as that of auto_ptr.