将Qt对象(QgraphicsItem)转换为C++类对象的最佳方法是什么
what is the best way to convert a Qt object(QgraphicsItem) into C++ class object
我正试图在类似的循环中将Qt对象转换为C++类对象
std::vector<PBWMPlugDeviceGraphicsItem*> deviceItms;
for(int i=0; i<fScene->items().size(); i++)
deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(fScene->items().at(i)));
其中PBWMPlugDeviceGraphicsItem
是C++类。似乎,当项目总数大于某个阈值(例如fScene->items().size() >900
)时,转换这些对象需要相当长的时间,因此我可以看到QGraphicsScene
上的操作非常缓慢。我读到dynamic_cast
存在严重的性能问题。
有没有其他好的/快速的方法可以达到同样的结果?
谢谢!
使用此:
for (auto p: fScene->items())
deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(p));
两个重要区别:
- 它只调用
fScene->items()
一次。除非该函数通过(const)引用返回,否则为每次迭代检索和丢弃容器是无用的开销,特别是如果内容不应该在迭代之间更改的话 - 它不使用索引并在
at()
中验证该索引,而是使用C++11用于带有自动类型化变量的循环。只有当您怀疑索引是否有效(例如,当它是从用户输入的)时,at()
才有用,但如果您不能编程一个简单的循环,那么您确实有更重要的问题
我没有进行使用vector::reserve()
预分配内存的第三次优化。如果你真的只有几个对象(是的,900是很少的),那么它可能很难被注意到。尽管如此,还是要对此进行一些研究,因为这是一个你应该了解的工具。
for(int i=0; i<fScene->items().size(); i++) deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(fScene->items().at(i)));
根据评论回复,fScene->items()
似乎返回了类似QList<QGraphicsItem *>
的内容。
编写代码时,会在每次循环迭代时创建并丢弃此QList的实例。因此,作为第一次优化,我会尝试在循环的外部获取列表一次,然后在循环内处理同一实例,避免在每次循环迭代时浪费列表的创建/销毁。
如果你可以使用C++11,我同意@Ulrich关于使用基于范围的for循环的建议:这将使更简单和更快。
编辑
在这里的一条评论中,你写道,你不能使用C++11,所以你不能享受基于范围的循环
那么,一个替代方案可能是:
// Get the collection of items once, outside the loop
QList<QGraphicsItem *> items = fScene->items();
// For each graphics item in the collection...
for (int i = 0; i < items.size(); i++) {
deviceItems.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(items.at(i)));
}
问题是调用QList::at
,它返回对列表项的引用,导致QList
在写分离时进行复制。
最小的解决方案是调用QList::value
来获取指针,而不是at
。
另一种解决方案是获取列表一次,如其他答案所述。即使使用at
,这种分离也只会发生一次。
您还可以通过强制转换或临时变量强制使用at
的const版本。
谢谢大家!你的建议很有用。我以以下方式实现(因为我不能使用C++11)
QList<QGraphicsItem*> temp= fScene->items();
for(int i=0; i<temp.size(); i++)
deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(temp[i]));
它运行得非常好。
非常感谢你提供的有用提示!我真的学到了一些新东西。
- 复制包含C++所有元素的对象!(构造函数和赋值,最佳实践?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 将FFMpeg AVFrame对象从C++应用程序流式传输到Python的最佳方法?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 保留计时器集合(对象与指针)的最佳方法
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- 从类中的对象调用类中的函数的最佳方法
- 这是使用构造函数初始化数组对象的最佳方法吗?
- 在 c++ 中重置大型对象实例的最佳方法是什么
- 将对象附加到智能指针向量的最佳方法
- 将对象数组作为参数传递的最佳方法是什么
- 如何为对象提供不同的接口(最佳)
- 调用列表中子对象方法的最佳方法
- 哪种数据结构是在一个向量中搜索和计数对象对的最佳数据结构
- 找到多组对象的最佳匹配的算法
- C++拥有持久对象的最佳方式
- 动态创建新对象的最佳方法
- 用C++编写返回对象的函数的最佳方法是什么
- 两者之间的最佳方法是什么:实例化对象或使用指针
- 确定两个文件路径引用同一文件对象的最佳方法是什么