我将加载多个XML文件,每个文件到QDomDocument
中,然后使用QMap
将标识字符串与每个文档相关联。我应该在 map 中存储QDomDocument
还是指向QDomDocument
的指针?即,以下哪个示例更符合Qt最佳设计规范。
我怀疑首选示例A。我看到的所有代码示例仅在堆栈上创建了一个本地QDomDocument
。并且,sizeof( QDomDocument )
是4个字节;因此,QDomDocument
可能是一个很薄的包装程序,可以对其进行浅拷贝而不会影响性能。
答: map 包含QDomDocument
实例
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包含指向
QDomDocument
实例的指针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
}
};
最佳答案
OP的怀疑是正确的:QDomDocument
通过其基类QDomNode
持有一个指向其实现(PIMPL)的指针。
尽管fonZ说的很正确,即原始对象将超出范围并被破坏,但存储在映射中的副本将使(共享)实现保持 Activity 状态。看一看the source,我们看到QDomDocument
一个空的析构函数,它的基类析构函数揭示了一个引用计数机制:
QDomNode::~QDomNode()
{
if (impl && !impl->ref.deref())
delete impl;
}
在复制构造中,计数增加:
QDomNode::QDomNode(const QDomNode &n)
{
impl = n.impl;
if (impl)
impl->ref.ref();
}
以及分配:
QDomNode& QDomNode::operator=(const QDomNode &n)
{
if (n.impl)
n.impl->ref.ref();
if (impl && !impl->ref.deref())
delete impl;
impl = n.impl;
return *this;
}
因此,方法A是合法且安全的,并且不涉及内存处理问题。
我还要指出,使用
QMap::insert
代替下标运算符的性能更高。正在做:
QDomDocument doc;
doc.setContent( &file );
docs["alpha"] = doc;
要么
docs["alpha"] = QDomDocument();
docs["alpha"].setContent( &file );
都会产生这个:
QDomDocument
对象(在第二个片段中是一个临时的)QDomDocument
对象,调用docs["alpha"]
使用
docs.insert("alpha", QDomDocument());
docs["alpha"].setContent( &file );
将仅调用临时构造函数和 map 项copy-constructor。
关于c++ - 我应该在堆上创建一个新的QDomDocument吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58101063/