Smart pointer in C ++
To put it simply, a smart pointer uses an object to model a pointer, which has the same meaning as a pointer->, * operation. in addition, the object constructor (obtain resources) is used to analyze the resources (release resources) to manage the resources, thus reducing Program Members manage the lifecycle of objects obtained through the new operation. According to moden C ++ design, we can construct smart pointers with many orthogonal features.
1.1 smart pointers in C ++ and objects in Java Some time ago I talked to my friends about Java. I feel that the objects in Java are smart pointers in C ++, but they have different resource release methods. In Java, you cannot use the "A;" Statement declaration in C ++ to obtain case A of class (a), but you must use the following statement to obtain it: AA = new. to release a, the application must notify GC (garbage collection function) to release the resources occupied by the instance. Of course, the objects in Java have slightly different functions from those in C ++, because pointers in C ++ do not have ". "operator, so smart pointers are generally not provided ". "operator, but all in Java are passed ". "operator to operate on objects, but we can The "->" operator of the smart pointer in C ++ is analogous to the "." Operator in Java.
.
1.2 reference counting smart pointer In C ++, a common smart pointer refers to the Count-type smart pointer: rcsmartptr. the implementation basis is as follows: first, rcobject exists, that is, an object that provides the reference counting interface. Secondly, the rcsmartptr object pointing to rcobject should exist. During the construction of rcsmartptr object, the pointer pointing to rcobject should be passed into rcsmartptr as a parameter. Therefore, each time an rcsmartptr object is added, a pointer to rcobject is added. Rcsmartptr can increase the reference count of rcobject by calling the reference count interface of rcobject. Similarly, you can call the rcobject reference count interface in the destructor of the rcsmartptr object to reduce the reference count of rcobject. Finally, the reference count is checked when the reference count of rcobject is operated. If the reference count is 0, rcobject will destroy itself and release the resources occupied by this object. In this way, we can hand over the management of resources to machines for management, removing the reliance on humans.
Reprinted statement:This article from http://www.cppblog.com/martin/archive/2009/03/03/martin_yahoo.html
========================================================== ======================================
Application Analysis of smart pointers in C ++
Some time ago, when I checked for Control Memory leakage, I finally found an error: When I used xmldom (COM), the dispatch pointer (release) was not released because I used an interface pointer repeatedly ), as a result, memory leakage occurs, and such errors (such as BSTR type leaks), the VC debugger and bondcheck are powerless. The solution seems to be only careful.
However, if you take a closer look, you can find that using the smart pointer provided by VC can avoid this problem.
In addition, Java programmers have been talking about the advantage of memory usage without management, and they always know that C ++ smart pointers can be used for simulation. However, I have never actually started the analysis. I simply wrapped it in C ++. In a rough view, it can achieve the same effect as Java. Of course, the C ++ object is more efficient and saves memory.
As mentioned above, I can only list the time relationships,CodeIt should be correct (but not checked ). There is no logical relationship between the beginning and end, but if we want to further apply the smart pointer of C ++, we believe it will serve as an example.
I. Application of smart pointers in MFC and ATL for Error Correction
1: How to conveniently view the memory used by the current process in windows.
Although the code is simple, there is a lot of use for Error Correction. You don't have to switch the task manager to view the memory usage. The Code is as follows:
Uint c_baseutil: getprocessmemoryused () { Uint uitotal = 0l; Handle hprocess =: getcurrentprocess (); Process_memory_counters PMC; If (: getprocessmemoryinfo (hprocess, & PMC, sizeof (PMC ))) Uitotal = PMC. workingsetsize; Return uitotal; } |
Note: memory usage is an unstable process. Therefore, you need to call it when the program is stable to ensure accuracy.
2: if you do not use the COM smart pointer when using the dispatch pointer of COM, it is prone to errors.
2.1: forget to release the pointer at all exits.
For example:
Ixmldomdocument * pdoc = NULL; Cocreateinstance (...) ...... Pdoc-> release (); |
Error: if an exception occurs in the intermediate code, pdoc cannot be properly released, resulting in Memory leakage.
2.2: The same pointer variable is used repeatedly, causing the dispatch pointer generated in the middle to fail to be released.
Ixmldomnode * pnode = NULL; If (failed (pdoc-> selectsinglenode (_ bstr_t ("workbook"), & pnode) | pnode = NULL) Throw (_ T ("selectsinglenode failed! ")); If (failed (pdoc-> selectsinglenode (_ bstr_t ("workbook"), & pnode) | pnode = NULL) Throw (_ T ("selectsinglenode failed! ")); |
Error: the second call is started when pnode is not released, resulting in Memory leakage. Or something similar to pnode = pnode2 is also a problem. You must call if (pnode) {pnode-> release (); pnode = NULL ;}
3: Use the COM smart pointer provided by MFC to solve the above problem.
Note: You can view the source code and see that the prototype of the smart pointer generated by # import is _ com_ptr_t.
3.1:
Ixmldomdocumentptr docptr = NULL; Docptr. createinstance (...) ...... |
There will be no problem, because docptr will be correctly released during the analysis.
3.2:
Ixmldomnodeptr nodeptr = NULL; If (failed (pdoc-> selectsinglenode (_ bstr_t ("workbook"), & nodeptr) | nodeptr = NULL) Throw (_ T ("selectsinglenode failed! ")); If (failed (pdoc-> selectsinglenode (_ bstr_t ("workbook"), & nodeptr) | nodeptr = NULL) Throw (_ T ("selectsinglenode failed! ")); |
No error will occur because _ com_ptr_t is overloaded with the & operator. The following operations are available when getting pointers: Hey.
Interface ** operator & () Throw () { _ Release (); M_pinterface = NULL; Return & m_pinterface; } |
3.3: nodeptr = nodeprt2, and no problem occurs:
Check the source code carefully and call attach in the = Operator. Attach calls _ release () first ();
3.4: Let's look at the value transfer: the copy constructor is as follows:
Template <> _ com_ptr_t (const _ com_ptr_t & CP) Throw () : M_pinterface (CP. m_pinterface) { _ Addref (); } |
Well, there will be no problem.
3.5: Finally, We will summarize the considerations when using the COM smart pointer:
· Do not force mycomptr = NULL before: couninitailize in the life cycle of the COM smart pointer. Otherwise, an error occurs.
· Do not mix smart pointers and general dispatch pointers, or call mycomptr-> release (). This violates the smart pointer's original intention and will report an error in the analysis structure.
4: Use ATL to provide smart pointers: ccomptr or ccomqiptr.
If you do not use the MFC framework, you must package idispatch to generate a smart pointer. You can also use the smart pointer provided by ATL. View the source code, and refer to the in-depth analysis of ATL book, found that the implementation is similar to _ com_ptr_t, the effect is consistent.
Ii. Let's look at the smart pointer of C ++.
1: When it comes to smart pointers, we must look at the auto_ptr provided by the Standard C ++. There are many restrictions on the use of auto_ptr. We will calculate the number one by one:
1.1: auto_ptr requires that an object only has one owner.
For example, the following is incorrect.
Classa * pA = new classa; Auto_ptr <classa> ptr1 (PA ); Auto_ptr <classa> ptr2 (PA ); |
1.2: auto_ptr cannot be passed by passing values.
The transfer of ownership will cause the passed smart pointer to lose its ownership of the pointer. If you want to transfer, you can use the reference method. Using the const reference method can also avoid the transfer of ownership in other methods in the program. In terms of ownership transfer: You can view the copy structure of auto_ptr and the source code of the = Operator, Which is omitted here.
1.3: Other considerations:
· Arrays are not supported.
· Note the meaning of its release. It does not reference the count, which is different from the smart pointer provided by COM. Release refers to releasing the pointer, that is, handing over the ownership of the pointer.
· The unique Pearl meaning of AUTO _ PTR in copying constructor and = operator determines that it cannot be a member of STL standard containers,
Well, after reading the above precautions, especially the third article, we can basically conclude that auto_ptr has little application value in actual application scenarios.
2: How to Get Smart pointers that support containers.
We use the auto_ptr prototype to create a smart pointer for reference counting, so that it supports the STL container standards. The implementation code is very simple. Refer to the Code in C ++ standard library. The key code is as follows:
template class countedptr { T * PTR; long * counter; public: // construct explicit countedptr (T * P = NULL) : PTR (P), count (New Long (1) {}< br> // analysis structure ~ Countedptr () {release () ;}< br> // copy structure countedptr (cont countedptr & P) : PTR (P. PTR), count (P. count) {++ * counter ;}< br> // = Operator countedptr & operator = (const countedptr & P) { If (this! = & P) { release (); PTR = P. PTR; counter = P. counter; + * counter; }< br> return * This; }< br> // others .... PRIVATE: void release () { If (-- * counter = 0) { Delete counter; Delete PTR; }< BR >} |
Okay. In this way, when the smart pointer is copied, the original pointer and the new pointer copy are both valid and can be applied to containers. Now, is the c ++ object packaged through countedptr similar to the Java object. As long as some necessary operators are added, they can be used as shared resources in the container.
Reprinted statement: This article is transferred from http://www.bccn.net/Article/kfyy/vc/jszl/200608/4310_2.html (programming China)
Recommendation reference: Android smart pointer (sp wp)