I recently read Don box's <com essence>. The second chapter mentions smart pointers. The author said that using smart pointers is dangerous. At that time, I did not agree with this opinion, in Microsoft's code, ccompt has never encountered any problems. However, only by practice can we know that the ccomptr is used in a piece of code I wrote yesterday. Let's take a look at the following code:
Ccomptr <ixmldomnode> spnoderectnum = spnode; <br/> If (strname = _ T ("ABC") <br/>{< br/> ccomptr <ixmldomnode> spnodeparent; // parent node <br/> spnodemetadata-> get_parentnode (& spnodeparent); <br/> assert (spnodeparent! = NULL); <br/> spnoderectnum-> release (); <br/> spnodeparent-> removechild (spnodemetadata, & spnoderectnum ); // Delete the current node <br/> assert (spnoderectnum! = NULL); <br/>}
The compilation link has passed. When a row of removechild is run, the assertion error P = 0 is displayed. Open atlcomcli. h and run the following code near row 150:
// The assert on operator & usually indicates a bug. if this is really <br/> // What is needed, however, take the address of the p Member explicitly. <br/> T ** operator & () Throw () <br/> {<br/> atlassert (P = NULL); <br/> return & P; <br/>}
Here, I can say "I got it". The second parameter of the removechild interface accepts the pointer, which means that the removechild interface will change the P value, however, smart pointers are not used in the removechild interface implementation, so the interface implementation will not automatically addref or releash, which will cause counter confusion and Memory leakage.
In the future, smart pointers must be within the controllable range.
Postscript: Today (09/09/25) afternoon, I talked to a colleague about the use of smart pointers. He said that my situation was discussed in chapter 2, in section 2.6, resource management and iunknown have a theorem R3:
R3. when the [In, out] parameter of the method or function is easy to rewrite and the initial value of the parameter is not empty. Note: The [out] parameter is often assumed to be "null when input", so the [out] parameter is never released when called.