繁体   English   中英

QMap插入QVector <QString> 通过指针还是值?

[英]QMap insert QVector<QString> by pointer or value?

我想建立一个设备地图,以便该地图包含:

QString'DeviceID'和QVector'Command List'

目前,我的QMap如下:

QMap<QString, QVector<QString> *> devices;

QVector<QString> *pCommands= new QVector<QString>;
//       :
// Fill pCommands with lots of data here
//       :
devices.insert(RadioID, pCommands);

但是我想知道这是否真的更好:

QMap<QString, QVector<QString>> devices;

QVector<QString> commands;
//       :
// Fill commands with lots of data here
//       :
devices.insert(RadioID, commands);

我确信我在某处读到Qt在复制数据时会做一些相当有效的事情。 我没有看到很多人将指针与Qt一起使用,并且我不得不经过QMap删除最后所有的QVector似乎很混乱...

我正在使用c ++ 11,所以也许某种移动语义可能在这里起作用?

编辑我修改了代码中的注释,以显示矢量不为空。 我还要指出,一旦存储数据,就不需要更改数据。

没有理由考虑手动分配向量更好。

当然,您只需要复制一个指针,而不是一个向量,但是复制一个空向量仍然非常快。 存储对象而不是指针的最大好处是您不需要手动进行内存管理。

我正在使用c ++ 11,所以也许某种移动语义可能在这里起作用?

如果QMap::insert支持移动语义,并且如果QVector像标准库中的标准库一样是可移动构造的,那么您确实可以将向量移动到地图中。 但是移动空向量与复制一样快。

如果QMap具有类似函数std::mapemplace ,那么您甚至都可以移动就地构建矢量。

我对Qt并不熟悉,因此您需要从文档中验证这些详细信息。 Qt是否支持移动语义并不能改变手动内存管理是一个痛苦的事实。


编辑:根据文档, QVector似乎是可移动的,但QMap不支持移动语义。 但是,正如Arpegius和文档所指出的那样, QVector会进行写时复制优化,因此只要不修改复制的向量,就不会复制数据。 复制空向量时,这实际上并不重要。


重新编辑

如果添加的向量中充满了数据,则复制确实非常昂贵,除非它保持不变。 搬家可以弥补这一点,但是QMap似乎不支持这一点。 但是,还有另一个技巧:插入一个空向量,然后将整个向量与图中的空向量swap

最简单且几乎是惯用的方式是:

QMap<QString, QVector<QString>> devices;

// Get the vector constructed in the map itself.
auto & commands = devices[RadioID];
// Fill commands with lots of data here - a bit faster
commands.resize(2);
commands[0] = "Foo";
commands[1] = "Bar";
// Fill commands with lots of data here - a bit slower
commands.append("Baz");
commands.append("Fan");

您会在Qt和其他代码中经常看到这种模式,这是在C ++ 98和C ++ 11上同样有效的最简单方法:)

这样,您就可以处理地图中已经存在的向量。 向量本身永远不会被复制。 向量的成员被复制,但是它们是隐式共享的,因此复制实际上是指针复制和原子引用计数增量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM