When you build and run the refCount project, you should get the following output in a console window:
dm1: refCount(pDom ++) = 1 dm2: refCount(pRoot ++) = 1 dm3: refCount(pElem ++) = 1 dm4: refCount(pElemOut ++) = 2 dm5: refCount(pElemA ++) = 3 dm6: refCount(pElem --) = 2 dm7: refCount(pElemOut --) = 1 dm8: refCount(pElemA ) = 1 dm9: refCount(pElem ++) = 1 dm10: refCount(pElemOut ++) = 2 dm11: refCount(pElemA --) = 0 dm12: refCount(pElem --) = 1 dm13: refCount(pElemOut --) = 0 dm14: refCount(pElem ++) = 1 dm15: refCount(pElemOut ++) = 2 dm16: refCount(pElem --) = 1 dm17: refCount(pElemOut --) = 0 dm18: refCount(pElemOut ++) = 2 dm19: refCount(pElemOut --) = 1 pDom->xml: <root><A><a>11</a></A><B>2</B></root> dm20: refCount(pDom --) = 0 dm21: refCount(pRoot --) = 0
The following remarks explain the various reference counts shown above. However, because reference counting is implementation-dependent, these discussions might or might not apply to other objects.
pDom
, which corresponds to the document element; pRoot
, which corresponds to the <root>
element; and pElem
, which corresponds to the <A>
element. Because these objects are new and distinct, the reference count equals 1 on each interface pointer. pElemOut
as returned from the call to pRoot->appendChild
method. Because pElemOut
is another reference to the pElem
object, when the call succeeds its reference count is 1 plus the count on pElem
that is, 2.pElemA
, which is a copy of pElemOut
; pElemA
is used to hold the <A>
element, so that pElem
and pElemOut
can be recycled to represent other elements. So far, pElem
, pElemOut
, and pElemA
all point to the same object. Therefore, the reference count on pElemA
is 3. pElem
, pElemOut
, and pElemA
after the Release
method has been called on pElem
and pElemOut
. These two interface pointers need to be released, because they will be used to add another element, <a>
, to the XML document. Remember that at this point in the code all three interface pointers still reference the same object. This means that the reference counts on them are correlated with each other. Failure to release pElem
or pElemOut
here will result in a memory leak. pElem
interface pointer, which points to a newly created IXMLDOMNode
object. This object, which represents the <a>
element, is to be added as a child of <A>
. Because this is a newly created object, the reference count on this interface pointer is 1.pElemOut
as returned from the call to pElemA->appendChild
method. This element is another reference to the pElem
object, <a>
. Therefore, when the call succeeds, its reference count is 1 plus the reference count on pElem
that is, 2.pElemA
, pElem
, and pElemOut
after the Release
method was called on each of the interface pointers. The system has released pElemA
because we are done with <A>
; when the reference count on pElemA
reaches zero, the system frees the memory object pointed to by the pElemA
interface pointer. Any attempt to access this object will result in access violation. The other two interface pointers are released because we are ready to move on to the next element, <B>
. Failing to release pElem
and pElemOut
here would result in a memory leak.pElem
interface pointer, which points to a newly created IXMLDOMNode
object, <B>
. This object is to be added as a child of <root>
. Because pElem
is not a copy of another interface pointer, the reference count is 1.pElemOut
as returned from the call to pRoot->appendChild
method. This element is another reference to the pElem
object, <B>
. Therefore, when the call succeeds, its reference count is 1 plus the reference count on pElem
that is, 2.pElem
and pElemOut
after the Release
method was called on each of the interface pointers. These two interface pointers are released because we are done with <B>
. Failing to release pElemOut
here would result in memory leak.pElemOut
as returned from the call to pDom->appendChild
method. This element is another reference to the pRoot
object, <root>
. Therefore, when the call succeeds, its reference count is 1 plus the reference count on pRoot
that is, 2.pElemOut
, pDom
, and pRoot
after the Release
method has been called on each of the interface pointers. These interface pointers are released because they are no longer needed. All the memory objects allocated in this application are freed when the application ends.