You said you would be C + +? --Smart pointers

Source: Internet
Author: User

Smart pointers are designed to provide a mechanism for proactively reclaiming memory in C + +, which requires manual delete after each new object. A little less attention on the memory leak.

Smart pointers can solve the problems encountered above.

Smart pointers Common in C + + contain (seven total): Std::auto_ptr boost::scoped_ptr boost::shared_ptr boost::intrusive_ptr Boost::scop Ed_array Boost::shared_array Boost::weak_ptr

In fact, a smart pointer is not a pointer, it is only a stack object. At the end of the life cycle of the stack object, the smart pointer calls the destructor to release its managed heap memory. All smart pointers overload the ' operator-> ' operator, which returns a reference to its management object. To be able to run some operations on managed objects.


Two methods:-Get () Access the smart pointer includes a bare pointer reference-reset () if the pass-in parameter is null or NULL, the smart pointer frees the currently managed memory.

If the pass-through argument is an object, the smart pointer frees the currently managed memory and manages the new incoming object.
The following is assumed to be the Managedobj class.

Class Managedobj{public:    managedobj (int val = 0): M_val (val)    {        cout<< "OBJ:" <<m_val<< Endl;    }    ~managedobj ()    {        cout<< "~obj:" <<m_val<<endl;    }    void Testfun ()    {        cout<< "Testfun:" <<m_info<<endl;    } Public:    string m_info;    int m_val;};

std::auto_ptrbelong to STL in namespace Std to add header file #include <memory> can be used. auto_ptr is typically used to manage a single heap of memory objects.
Look at the following example:
Std::auto_ptrvoid testAutoPtr1 () {    auto_ptr<managedobj> atptr (New Managedobj (1, "initialize"));    if (Atptr.get ())    //Infer whether the smart pointer is empty    {        atptr->testfun ();        Atptr.get ()->m_info + = "1st append";    Get () returns a reference to the bare pointer        atptr->testfun ();        (*atptr). M_info + = "2nd append";        Operator* returns the object managed by the smart pointer        (*ATPTR). Testfun ();    }}
The result of the execution is:
OK, there seems to be no problem.
We went on to test:
void TestAutoPtr2 () {    auto_ptr<managedobj> atptr (New Managedobj (1, "initialize"));    if (Atptr.get ())    //Infer whether the smart pointer is empty    {        auto_ptr<managedobj> atPtr2;        ATPTR2 = atptr;               Reason in this line of code        Atptr2->testfun ();        Atptr->testfun ();          Crash in this line of code    }}
The result of the execution is:
Debugging found the last line of code out of the bug. Why is it? In fact, ATPTR2 deprived the atptr of the full power of memory management, resulting in atptr floating.
Keep testing.

void TestAutoPtr3 () {    auto_ptr<managedobj> atptr (New Managedobj (1, "initialize"));    if (Atptr.get ())    //Infer whether the smart pointer is empty    {        atptr.release ();}    }
The result of the execution is:
It seems to be a bug again. We do not see any sign of the destructor being called, memory leaks out: (Tease me, why so many bugs?)

)
Don't worry. The third Test function should be the correct one.

void TestAutoPtr3 () {    auto_ptr<managedobj> atptr (New Managedobj (1, "initialize"));    if (Atptr.get ())    //Infer whether the smart pointer is empty    {        //managedobj* temp = atptr.release ();        Delete temp;        or        atptr.reset ();    }}

This is the result we want to see.


So we also found that. Auto_ptr's release () function simply frees up memory and does not really release memory.
Summary: auto_ptr is typically used to manage a single heap of memory objects.

But note: A. Remember to use "operator=". In case of real use, don't use the old object again.

B. The release () method does not release memory but only yields the full right.
The above auto_ptr is really not very convenient to use, and we also have to pay attention to avoid its use defects.

So there are some smart pointers in boost, as described below.
Boost::scoped_ptr
Namespace boost is included in the Boost library #include <boost/smart_ptr.hpp> can be used.


For an installation tutorial on the Boost library: http://blog.csdn.net/misskissc/article/details/9793645http://www.cnblogs.com/xuqiang/archive/ 2011/05/08/2040420.html
Similar to auto_ptr. Scoped_ptr can also manage an object for a single heap of memory, but it has all the power and therefore avoids the auto_ptr flaw .
Ok. On the code test.

Boost::scoped_ptrvoid testscopedptr () {boost::scoped_ptr<managedobj> scptr (New MANAGEDOBJ (1, "initialize")) ; if (Scptr.get ()) {scptr->testfun (); Scptr.get ()->m_info + = "1st append";//Get () returns a reference to the bare pointer scptr->testfun ();(* SCPTR). M_info + = "2nd append";//Operator* Returns the object managed by the smart Pointer (*scptr). Testfun ();//scptr.release ();//Error SCOPED_PTR No member release//boost::scoped_ptr<managedobj> SCPTR2;//SCPTR2 = scptr;//Error scoped_ptr<t>::operator= ( Const scoped_ptr<managedobj> &) Not available}}
The result of the execution is:
Note the code of the gaze section. Scoped_ptr does not have a release () function that masks the operator= operation, so there is no memory leak and crashes in auto_ptr. But it also brings with it a new problem. We can't copy smart pointers.
So there's the next shared_ptr.
boost::shared_ptrNamespace boost is included in the Boost library #include <boost/smart_ptr.hpp> can be used.


Because Scoped_ptr does not agree to the full right of the assigned copy to exclusive memory. The shared_ptr here is dedicated to solving the problem of the full weight sharing of smart pointers in memory. The reference count is used internally.

Come on, test it.

Boost::shared_ptrvoid testsharedptr (boost::shared_ptr<managedobj> ptr) {    ptr->testfun ();    cout<< "shared_ptr use_count:" <<ptr.use_count () <<endl;} void TestSharedPtr1 () {    boost::shared_ptr<managedobj> shptr (New Managedobj (1, "initialize"));    if (Shptr.get ())    {        shptr->testfun ();        Shptr.get ()->m_info + = "1st append";    Get () returns a reference to the bare pointer        shptr->testfun ();        (*shptr). M_info + = "2nd append";        Operator* returns the object managed by the smart pointer        (*SHPTR). Testfun ();    cout<< "shared_ptr1 use_count:" <<shptr.use_count () <<endl;    Testsharedptr (shptr);    cout<< "shared_ptr1 use_count:" <<shptr.use_count () <<endl;     Shptr.release (); Error shared_ptr no member release}
The result of the execution is:
Can see. The call to the Testsharedptr () function runs a copy operation, and the reference count inside the smart pointer is +1. After the function call ends, the reference count itself is active-1.

Several of the smart pointers described above are for the memory management of a single object.

In fact, smart pointers can also manage arrays, followed by Boost::scoped_array and Boost::shared_array.


- Boost::scoped_array belongs to boost library in namespace boost Add header file #include <boost/smart_ptr.hpp> can be used.
The Boost::scoped_array is used to manage dynamic arrays. is also the sole right to enjoy all.


On the code:

Boost::scoped_arrayvoid Testscopedarray () {    boost::scoped_array<managedobj> scArr (new ManagedObj[2]);        Dynamic array Initialization    if (Scarr.get ())    {        scarr[0].testfun ();        Scarr.get () [0].m_info + = "[0] 1st append";        Scarr[0].testfun ();        (*scarr) [0].m_info + = "2st append";    Error Scoped_array no reload operator*        //(*scarr) [0].testfun ();        Scarr[0].release ();                        Error Scoped_array no member release        boost::scoped_array<managedobj> SCARR2;        SCARR2 = Scarr;                Error operator= non-access blocked operator= forbidden copy    }}
The result of the execution is:
The use and boost::scoped_ptr of Boost::scoped_array are roughly the same. All rights are forbidden for all copies to be exclusive.

Note: Boost::scoped_array does not overload the operator* operator
- Boost::shared_array belongs to boost library in namespace boost Add header file #include <boost/smart_ptr.hpp> can be used.


A reference count is used internally to solve the problem of parameter passing and copy assignment.


The following code tests are given:

Boost::shared_arrayvoid Testsharedarray (boost::shared_array<managedobj> pArr) {cout<< "Shared_arr use    _count: "<<parr.use_count () <<endl;    Boost::shared_array<managedobj> Ptemparr;    Ptemparr = PARR; cout<< "Shared_arr use_count:" <<parr.use_count () <<endl;}    void TestSharedArray1 () {boost::shared_array<managedobj> Sharr (new managedobj[2]);        if (Sharr.get ()) {sharr[0].testfun ();        Sharr.get () [0].m_info + = "[0] 1st append";        Sharr[0].testfun ();        Sharr[1].testfun ();        Sharr.get () [0].m_info + = "[1] 1st append";        Sharr[1].testfun ();    (*sharr) [0].m_info + = "[0] 2nd append";    Error does not overload the operator* operator} cout<< "shared_arr1 use_count:" <<sharr.use_count () <<endl;    Testsharedarray (Sharr); cout<< "shared_arr1 use_count:" <<sharr.use_count () <<endl;}
The result of the execution is:

boost::weak_ptrNamespace boost is included in the Boost library #include <boost/smart_ptr.hpp> can be used.
If we only care if we can use the object. Without concern for internal reference counting. BOOST::WEAK_PTR is the Boost::shared_ptr Observer (Observer) object, which means that boost::weak_ptr is only referring to Boost::shared_ptr. However, it does not update its reference count. After the observed shared_ptr fails, the weak_ptr correspondence also fails.


The Test code:

Boost::weak_ptrvoid testweakptr () {    boost::weak_ptr<managedobj> wptr;    Boost::shared_ptr<managedobj> shptr (New Managedobj (1, "initialize"));    cout << "Testweakptr boost::shared_ptr usecount:" << shptr.use_count () << Endl;    Wptr = shptr;    cout << "Testweakptr boost::shared_ptr usecount:" << shptr.use_count () << Endl;}
The result of the execution is:
We found that the assignment operation did not change the reference count. Boost::weak_ptr Many others are used for the following occasions: Define a weak_ptr in the base class to observe shared_ptr in its subclasses. The base class simply depends on whether its weak_ptr is empty and knows that the subclass has no value assigned to itself, and does not affect the reference count of shared_ptr in the subclass. thus reducing complexity. Better manage objects.
boost::intrusive_ptrNamespace boost is included in the Boost library #include <boost/smart_ptr.hpp> can be used.
Intrusive_ptr is a plug-in smart pointer that does not have a reference count inside it and needs to increase the reference count itself, or it compiles an error.



OK so far, seven smart pointers have basically been introduced.


References:

http://blog.csdn.net/xt_xiaotian/article/details/5714477


The complete code is here .

#include <iostream> #include <memory> #include <string> #include <boost/smart_ptr.hpp>//add  Header file//namespace using namespace std;using namespace boost;//heap obj classclass managedobj{public:managedobj (int val = 0, String info = ""): M_val (Val), M_info (info) {cout<< "OBJ:" &LT;&LT;M_VAL&LT;&LT;M_INFO&LT;&LT;ENDL;} ~managedobj () {cout<< "~obj:" &LT;&LT;M_VAL&LT;&LT;M_INFO&LT;&LT;ENDL;} void Testfun () {cout<< "Testfun:" &LT;&LT;M_INFO&LT;&LT;ENDL;} Public:string M_info;int m_val;};/ /std::auto_ptrvoid testAutoPtr1 () {auto_ptr<managedobj> atptr (New Managedobj (1, "initialize")); if (Atptr.get () //Infer If the smart pointer is empty {atptr->testfun (); Atptr.get ()->m_info + = "1st append";//Get () returns a reference to the bare pointer atptr->testfun ();(* ATPTR). M_info + = "2nd append";//Operator* Returns the object managed by the smart Pointer (*atptr). Testfun ();}} void TestAutoPtr2 () {auto_ptr<managedobj> atptr (New Managedobj (1, "initialize")), if (Atptr.get ())//infer whether the smart pointer is empty { auto_ptr<managedobj> ATPTR2;ATPTR2 = Atptr;aTptr2->testfun (); Atptr->testfun ();}} void TestAutoPtr3 () {auto_ptr<managedobj> atptr (New Managedobj (1, "initialize")), if (Atptr.get ())//infer whether the smart pointer is empty { managedobj* temp = Atptr.release ();//delete temp;//or Atptr.reset ();}} Boost::scoped_ptrvoid testscopedptr () {boost::scoped_ptr<managedobj> scptr (New MANAGEDOBJ (1, "initialize")) ; if (Scptr.get ()) {scptr->testfun (); Scptr.get ()->m_info + = "1st append";//Get () returns a reference to the bare pointer scptr->testfun ();(* SCPTR). M_info + = "2nd append";//Operator* Returns the object managed by the smart Pointer (*scptr). Testfun ();//scptr.release ();//Error SCOPED_PTR No member release//boost::scoped_ptr<managedobj> SCPTR2;//SCPTR2 = scptr;//Error scoped_ptr<t>::operator= ( Const scoped_ptr<managedobj> &) Not available}}//boost::shared_ptrvoid testsharedptr (boost::shared_ptr< Managedobj> ptr) {ptr->testfun ();cout<< "shared_ptr use_count:" <<ptr.use_count () <<endl;} void TestSharedPtr1 () {boost::shared_ptr<managedobj> shptr (New Managedobj (1, "InitializE ")), if (Shptr.get ()) {shptr->testfun (); Shptr.get ()->m_info + =" 1st append ";//Get () returns a reference to the bare pointer shptr->testfun ( );(*shptr). M_info + = "2nd append";//Operator* Returns the object managed by the smart Pointer (*shptr). Testfun (); cout<< "shared_ptr1 use_count:" <<shptr.use_count () <<endl;testsharedptr (SHPTR);cout<< " SHARED_PTR1 use_count: "<<shptr.use_count () <<endl;//shptr.release ();//Error shared_ptr no member release}// Boost::scoped_arrayvoid Testscopedarray () {boost::scoped_array<managedobj> scArr (new ManagedObj[2]);// Dynamic array Initialization if (Scarr.get ()) {scarr[0].testfun (); Scarr.get () [0].m_info + = "[0] 1st append"; Scarr[0].testfun ();//(*scarr) [ 0].m_info + = "2st append";//error Scoped_array not overloaded operator*//(*scarr) [0].testfun ();//scarr[0].release ();/error Scoped_array No member releaseboost::scoped_array<managedobj> SCARR2;//SCARR2 = scarr;//error operator= not available Shielded operator= Forbidden Copy}}//boost::shared_arrayvoid Testsharedarray (boost::shared_array<managedobj> pArr) {cout< < "Shared_arr USE_count: "<<parr.use_count () <<endl;boost::shared_array<ManagedObj> Ptemparr;ptemparr = Parr;cout << "Shared_arr use_count:" <<parr.use_count () <<endl;} void TestSharedArray1 () {boost::shared_array<managedobj> Sharr (new managedobj[2]), if (Sharr.get ()) {sharr[0]. Testfun (); Sharr.get () [0].m_info + = "[0] 1st append"; Sharr[0].testfun (); Sharr[1].testfun (); Sharr.get () [1].m_info + =] [1] 1st append "; Sharr[1].testfun ();//(*sharr) [0].m_info + =" [0] 2nd append ";//Error not overloaded operator* operator}cout<<" SHARED_ARR1 use_count: "<<sharr.use_count () <<endl;testsharedarray (Sharr);cout<<" SHARED_ARR1 use _count: "<<sharr.use_count () <<endl;} Boost::weak_ptrvoid testweakptr () {boost::weak_ptr<managedobj> wptr;boost::shared_ptr<managedobj> Shptr (New Managedobj (1, "initialize")) cout << "Testweakptr boost::shared_ptr usecount:" << shptr.use_ Count () << endl;wptr = Shptr;cout << "Testweakptr boost::shared_ptr USecount: "<< shptr.use_count () << Endl;} Boost::intrusive_ptrvoid testintrusiveptr () {//boost::intrusive_ptr<managedobj> intPtr (new ManagedObj[1], FALSE);//error to add itself to the reference count}//main functionint main (void) {//-----std::auto_ptr-----//testautoptr ();//TESTAUTOPTR2 () ;//testautoptr3 ();//-----boost::scoped_ptr-----//testscopedptr ();//-----BOOST::SHARED_PTR-----//TESTSHAREDPTR1 ();//-----Boost::scoped_array-----//testscopedarray ();//-----Boost::shared_array-----//testsharedarray1 ();//- ---boost::weak_ptr-----testweakptr (); return 0;}


You said you would be C + +? --Smart pointers

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.