smartpointer + dom



  • heyho,

    habe mir mal smartpointer zu gemüte geführt, vorallem auf basis dieses threads.
    nun stellt sich mir eine frage:

    ich arbeite mit xml dateien, und bisher ist das auslesen recht umständlich, da ich 1.
    immer abfragen muss, ob das object was ich auslesen will, existiert, und wenn nich, ich nich einfach returnen kann, sondern erst alle DOM objecte releasen muss.
    jetzt hatte ich die idee, das ganze dem smartpointer scope_ptr zu überlassen. d.h. wenn die funktion verlasse, das mein DOM.release() aufruft, und ich mich nicht mehr darum kümmern muss, eben jenes freizugeben, da es nun teilweise wirklich viele ifs sind 😛

    nun zu meiner frage, ist das mit der momentanen funktionalität des scope_ptr möglich, oder muss ich ihn erweitern?
    oder gibt es hier doch eine komplett andere möglichkeit, die ich übersehe?

    um mal ein codebeispiel zu nennen, was ich meine:

    MSXML2::IXMLDOMDocument2Ptr pXMLDom = NULL;
        HRESULT hr;
    
        CoInitialize(NULL);
    
        hr = pXMLDom.CreateInstance(__uuidof(DOMDocument40));
        if (hr == S_OK)
        {
            // some stupid stuff
            IXMLDOMNodePtr pNode = pXMLDom->selectSingleNode("Map");
            if (pNode)
            {
                // and so on
    
            }   // if (pNode)
            else
                result = MAP_RESULT_CORRUPT_FILE;
    
            if (pNode)
                pNode.Release();
        }
        else    // if (hr == S_OK)
            result = MAP_RESULT_FAILED;
    
        if (pXMLDom)
            pXMLDom.Release();
    
        CoUninitialize();
    
        return result;
    

    so ist das momentan mit xml gelößt .



  • boost::scoped_ptr ruft immer nur delete auf. Das heisst, du müsstest deine Ressourcen-Klasse mit einem Destruktor versehen, der release() aufruft. Ist generell nicht schlecht, da du so RAII-Semantik hast.

    Eine C++11-Alternative wäre std::unique_ptr mit einem speziellen Deleter.



  • d.h. ich muss ne klasse von den DOM objecten erben lassen . klingt umständlich^^

    oder ne template klasse... wäre ne alternative^^



  • Weder noch. Du sollst einen Wrapper schreiben, wenn du RAII-Objekte willst. Oder du benutzt wie gesagt Custom-Deleters, der Smart-Pointer selbst ist dann dein Wrapper.



  • MSXML definiert schon Smart Pointer und Du benutzt sie auch schon!!!
    Es ist nicht nötig Release() aufzurufen!

    Einzig bei deinem Bsp. ist zu beachten, dass Du einen zusätzlichen Scope benötigst um alle Smart Pointer zu zerstören bevor Du CoUnitialize() aufrufst!



  • ist es denn dann sinnvoll den CoInitialize() und CoUninitialize() vor die funktion zu ziehen?



  • Ich würde CoInitialize(..) / CoUninitialize(..) im main(..) aufrufen. Danach wird es vorausgesetzt. Solange es Referenzen auf COM Objekte gibt darf CoUninitialize(..) nicht aufgerufen werden.

    COMInitialization
    {
       COMInitialization()
       {
          CoInitialize();
       } 
       ~COMInitialization()
       {
          CoUninitialize();
       }
    };
    
    int main()
    {
       COMInitialization comInitialization;
       {
          // Benutze hier COM
       }
    }
    

    Natürlich noch die HRESULTs prüfen, etc.



  • ok, danke 🙂


Anmelden zum Antworten