Auto PTR is an intelligent pointer provided by C++98 Standard library, but it has been explicitly stated by C++11 that it is no longer supported.
Auto PTR has the following defects:
- Auto ﹣ PTR has copy semantics, and the source object becomes invalid after copying, which may cause serious problems; while unique ﹣ PTR has no copy semantics, but provides mobile semantics. Such errors are no longer possible, because it is obvious that std::move() must be used for transfer.
#include <iostream> #include <tr1/memory> using namespace std::tr1; using namespace std; class A { public: string id; A(string id):id(id) { cout<<id<<": Constructor"<<endl; } ~A() { cout<<id<<": Destructor"<<endl; } }; int main() { auto_ptr<A> auto_ap(new A("auto_ptr")),auto_bp; cout<<auto_ap.get()<<endl; auto_bp = auto_ap; cout<<auto_ap.get()<<endl; unique_ptr<A> unique_ap(new A("unique_ptr")),unique_bp; cout<<unique_ap.get()<<endl; // Unique? BP = unique? AP; / / an error is reported unique_bp = move(unique_ap); cout<<unique_ap.get()<<endl; return 0; }
Operation result:
auto_ptr: constructor 0x6115d0 0 unique_ptr: constructor 0x6115f0 0 unique_ptr: destructor Auto PTR: destructor
- Auto PTR cannot be used as a container element, and unique PTR can be used as a container element. Because the copy and assignment of auto PTR are destructive, they do not meet the requirements of the container: after copy or assignment, the two objects must have the same value.
- Auto PTR cannot point to a dynamic array. Unique PTR can point to a dynamic array. Because the unique PTR has an overloaded version of unique PTR < T [] > delete [] is called when destroying dynamic objects.
#include <iostream> #include <memory> using namespace std; class A { public: string id; A(string id):id(id) { cout<<id<<": Constructor"<<endl; } ~A() { cout<<id<<": Destructor"<<endl; } }; int main() { //Auto PTR < a [] > auto AP (new a [1] {a ("unique PTR")}); / / an error is reported unique_ptr<A[]> unique_ap(new A[1]{A("unique_ptr")}); return 0; }
- Auto PTR cannot customize the deleter, while unique PTR can.
#include <iostream> #include <string> #include <tr1/memory> using namespace std; using namespace std::tr1; class A { public: string id; A(string id):id(id) { cout<<id<<": Constructor"<<endl; } ~A() { cout<<id<<": Destructor"<<endl; } }; int main() { unique_ptr<A,void(*)(A*)> unique_ap( new A[2] { A("unique_ptr0"),A("unique_ptr1") }, [](A *a) { delete []a; }); return 0; }
Operation result:
unique_ptr0: constructor unique_ptr1: constructor unique_ptr1: destructor unique_ptr0: destructor
#include <iostream> #include <string> #include <tr1/memory> using namespace std; using namespace std::tr1; class Test { public: Test(string s) { str = s; cout<<"Test creat\n"; } ~Test() { cout<<"Test delete:"<<str<<endl; } string& getStr() { return str; } void setStr(string s) { str = s; } void print() { cout<<str<<endl; } private: string str; }; int main() { auto_ptr<Test> ptest(new Test("123")); ptest->setStr("hello "); ptest->print(); ptest.get()->print(); //The member function get() returns a raw pointer ptest->getStr() += "world !"; (*ptest).print(); //Test creat //Test delete:hello world ! ptest.reset(new Test("123")); //The member function reset() rebinds the object it points to, and the original object is released ptest->print(); //Ptest2 will take over the original memory management rights of ptest, and it will become a null pointer. If ptest2 is not null, it will release the original resources auto_ptr<Test> ptest2(new Test("456")); ptest2 = ptest; ptest2.release(); //Ptest2 - > print(); / / segment error (core dumped) //if(ptest == NULL) cannot be used to determine whether a smart pointer is null. if(ptest.get() == NULL) should be used if(ptest.get() == NULL) { cout<<"ptest = NULL\n"; } //The member function is release, which just assigns the smart pointer to null, but the memory it originally points to is not released, which is equivalent to that it just releases the ownership of the resource //ptest.release(); return 0; }