gpt4 book ai didi

c++ - 我应该在堆上创建一个新的 QDomDocument 吗?

转载 作者:行者123 更新时间:2023-11-30 02:14:24 24 4
gpt4 key购买 nike

我将加载多个 XML 文件,每个文件都放入一个 QDomDocument 中,然后使用一个 QMap 将一个标识字符串与每个文档相关联。我应该在 map 中存储 QDomDocument 还是指向 QDomDocument 的指针?即,以下哪个示例更符合 Qt 最佳设计实践。

我怀疑示例 A 是首选。我看到的所有代码示例只是在堆栈上创建一个本地 QDomDocument。并且,sizeof( QDomDocument ) 是 4 个字节;因此,QDomDocument 可能是一个薄包装器,可以进行浅层复制而不会对性能造成太大影响。

A: 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说原始对象将超出范围并被销毁是正确的,存储在映射中的拷贝将使(共享)实现保持事件状态。看看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 对象(临时的,在第二个片段中)
  • 调用 docs["alpha"]
  • 创建了另一个 QDomDocument 对象(在 map 内部)
  • 后者分配给第一个。

使用

docs.insert("alpha", QDomDocument());
docs["alpha"].setContent( &file );

只会调用临时构造函数和 map 项复制构造函数。

关于c++ - 我应该在堆上创建一个新的 QDomDocument 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58101063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com