I will load multiple XML files, each into a QDomDocument, and then use a QMap to associate an identifying string with each document. Should I store a QDomDocument or a pointer to a QDomDocument in the map? i.e., which of the following examples is more in keeping with Qt best design practices.
I suspect that example A is preferred. All the code samples I see just create a local QDomDocument on the stack. And, sizeof( QDomDocument ) is 4 bytes; so, QDomDocument is probably a thin wrapper that can be shallow copied without much of a performance hit.
A: Map contains QDomDocument instances
class Core
{
private:
QMap<QString, QDomDocument> docs;
public:
Core( void )
{
QFile file( "alpha.xml" );
file.open( QIODevice::ReadOnly );
QDomDocument doc;
doc.setContent( &file );
docs["alpha"] = doc;
// ... etc for other XML files
}
QString findThing( QString const & docName, QString const & thingName )
{
QDomDocument doc = docs[docName];
// ... search the doc for the thing with the given name
}
};
B. Map contains pointers to QDomDocument instances
class Core
{
private:
QMap<QString, QDomDocument *> docs;
public:
Core( void )
{
QFile file( "alpha.xml" );
file.open( QIODevice::ReadOnly );
QDomDocument * pDoc = new QDomDocument();
pDoc->setContent( &file );
docs["alpha"] = pDoc;
// ... etc for other XML files
}
QString findThing( QString const & docName, QString const & thingName )
{
QDomDocument * pDoc = docs[docName];
// ... search the doc for the thing with the given name
}
};
The OP suspicions are quite right:
QDomDocumentholds a pointer to its implementation (PIMPL) through its base class,QDomNode.While fonZ is right in saying the original object will go out of scope and destroyed, the copy stored in the map will keep the (shared) implementation alive. Taking a look at the source, we see an empty destructor for
QDomDocument, and its base class destructor reveals a reference counting mechanism:the count gets incremented in copy construction:
and in assignment as well:
thus method A is legal and safe, and bears no memory handling concerns.
I would also point out that using
QMap::insertinstead of the subscript operator is a bit more performant.Doing:
or
will both produce this:
QDomDocumentobject is created (a temporary, in the second snippet)QDomDocumentobject is created (inside the map) callingdocs["alpha"]Using
will only call the temporary constructor and the map item copy-constructor.