【问题标题】:Convert (Qt) container of objects into container of const objects efficiently?有效地将(Qt)对象容器转换为 const 对象容器?
【发布时间】:2015-08-26 19:38:58
【问题描述】:

我的具体问题是我有一个 QMultiHash<Foo,Bar*> private 成员,我想提供对哈希值的访问,但对项目的 const 版本提供访问权限,声明:

QList<const Bar*> getBars(Foo f) const;

有没有一种更简洁/更有效的方式来“约束”Qt 容器中的项目,而不是使用 const 项目创建一个丑陋/低效的新容器并进行复制来自源的指针(在这种情况下为QMultiHash&lt;K,V&gt;::values())?

恐怕答案可能是“不”,但我想确保我没有错过一些 Qt/C++(03) 语法魔法来做到这一点。

【问题讨论】:

  • stackoverflow.com/questions/10265695/…我不知道解决方案(除了可能是一个巨大的丑陋黑客),但for循环有这么大吗?它只是复制指针,我怀疑它会影响您的性能 - 除非 QList 很大并且您有非常高的性能要求。
  • 在这种特殊情况下,这没什么大不了的(我已经继续并以这种方式实现了它)。但它冒犯了我的风格,在我的应用程序的其他情况下(交互式数据可视化),我可能需要对大约 1000-10000 个图表字形对象的容器进行交互式 UI 操作,其中我正在检查但不更改字形对象没有滞后 UI 只是为了获得一个 const 指针的容器。

标签: c++ qt


【解决方案1】:

有两种方法。您提到的明显方法是使用 C++11 并将其自己转换为 QList&lt;const Bar*&gt;

QList<const Bar*> getList() const
{
    QList<const Bar*> list;

    for(Bar *b : m_List) //where m_List is your private memebr QList<Bar*>
        list << b;

    return list;
}

另一种方法是将QList 本身转换为const QList&lt;Bar*&gt;,这可以通过从 const 函数返回列表“神奇地”完成,例如:

const QList<Bar*> getList() const
{ 
    return m_List; //where m_List is your private memebr QList<Bar*>
} 

使用哪一个取决于您的需要。根据您的描述,您需要检查元素而不更改它们。听起来您实际上根本不需要可修改列表。第一个变体听起来已经有点矫枉过正了。您想要const Bar* 大概是因为您不希望它在检查项目时意外更改。例如,要检查所有元素,您可以这样做(为每个元素自动添加 const):

for(const Bar *b : myObject->getList())
    //do only const stuff with b

除非您有充分的理由返回QList&lt;const Bar*&gt;,例如您需要修改列表,否则不值得麻烦和性能损失。当您以我描述的方式使用 C++11 for 或使用 const 迭代器自己访问它时,您可以使用 const 限制 Bar *。根据我收集的信息,我建议使用它而不是将(可能很大)列表的值转换为 const。

最后一个提示,如果您的列表非常庞大并且您需要每一滴性能,请考虑:

const QList<Bar*> &getList() const

我相信在之前的代码 sn-p 中,Qt 的隐式共享本身就是这样做的,但这确保了在您检查列表时永远不会复制或修改列表。

【讨论】:

  • 请注意,我的实际成员是一个 QMultiHash,我想要提供 const 访问的是来自 QMultiHash::values(). 的值列表,因此最后一个 const 引用不是一个选项。另请注意,提供此类访问器的主要原因是 const 正确性;另外,我不希望依靠自己或其他人的好意来适当地访问列表(通过 const iterators 等)。
  • @eclarkso 在这种情况下,您唯一的选择是自己创建这样的列表。即使存在可以为您创建它的函数,它也会做几乎相同的事情 - 使用 const 元素创建新列表。无论如何,使用 C++11 来完成它,因为它是目前可用的最快方式。除非由于列表太大(并且转换需要太长时间)而导致检查时间过长而遇到性能问题,否则应该没有问题。如果性能确实成为问题,您可能必须重新考虑您的优先级或设计。祝你好运!
【解决方案2】:

没有有效的方法来“构造”现有数组中的对象。但是如果你真的存储指针列表。在简单循环中将非“const”指针转换为“const”指针可能会很快吗?! (即制作新列表) 第二种解决方案是当您填写该列表时,最初在列表中创建“const”对象。 第三种方法是让您的列表中自己的子类可以返回only“const”引用或迭代器到存储的元素。

【讨论】:

  • 希望你在没有代码示例的情况下理解我。如果没有,请告诉我。我会解释更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-21
相关资源
最近更新 更多