Liquid XML Data Binder (C++, Java, VB6) / Reference / C++ / Key Concepts / SmartPointers
In This Topic
    In This Topic

    This is an important concept to understand up front. The lifetimes of all the generated classes are controlled by reference counting.

    This is exactly the same way COM works, you have an AddRef and a Release on each object, and when the reference count reaches 0 the object is deleted.

    Now if you've ever worked with COM you'll know that this can be a bit of a pain, ensuring that each AddRef has an associated Release etc. But there was good news when Microsoft added the _com_ptr_t class. This is essentially a very simple template class that wraps a COM object and allows you to pass it around by value. When ever the smart pointer is copied, AddRef is called, and when ever the smart pointer goes out of scope and is deleted, Release is called. Now this made working with COM a whole lot simpler, we could now just treat COM objects as objects you could pass by value.

    Well that is exactly how things work when using the generated libraries. The generated libraries will always return objects wrapped with a smart pointer, so you should always be manipulating the objects via there SmartPointer wrapper classes. This way you will never have to deal with reference counting directly, and things are pretty straight forward.

    The generated libraries typedef a smart pointer wrapper for each generated class. The smart pointer class has 'Ptr' appended to it.
    So if we have a generated class CElmSequence, the smart pointer for this class would be CElmSequencePtr, defined like this.

    typedef CSmartPtr<CElmSequence> CElmSequencePtr;


    Lets look at an example - the classes have been simplified for simplicity.

    class CBasicElement , public virtual LtXmlLib20::CXmlObjectBase
         static CBasicElementPtr CreateInstance();
         std::tstring GetStringElm();
         void SetStringElm(std::tstring val);

    class CElmSequence , public virtual LtXmlLib20::CXmlObjectBase
         static CElmSequencePtr CreateInstance();
        CBasicElementPtr GetBasicElement();
        void SetBasicElement(CBasicElement* value);

    // Due to the way all the generated classes are defined,
    // it is not possible to create them directly. Instead we
    // must use a static method - CreateInstance. This ensures
    // that the smart pointers are used.
    CElmSequencePtr spElm = CElmSequence::CreateInstance();

    // Now we have our ElmSequence we can look at one of
    // its child objects BasicElement.
    // Note: we don't need to do any reference counting etc
    //            the smart pointer takes care of all of that for us.
    spElm->GetBasicElement()->SetStringElm(_T("Test Data"));

    // spElm will call Release when it goes out of scope, because there
    // are not other references to it, at this point the underlying
    // CElmSequence object will be deleted.