Explanation on the use of C + + intelligent pointer auto ﹣ PTR

Posted by emorr1981 on Fri, 20 Dec 2019 17:34:48 +0100

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;
}

Topics: Mobile