我想建立一个设备地图,使地图包含:
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,所以也许某种移动语义可以在这里工作?
修改 我修改了代码中的注释,以显示向量不为空。 另外,我会声明一旦存储数据,我就不需要更改数据。
答案 0 :(得分:4)
没有理由考虑手动分配矢量更好。
当然,你只需要复制一个指针,而不是一个向量,但是复制的空向量仍然很快。存储对象而不是指针的最大好处是你不需要进行手动内存管理。
我正在使用c ++ 11,所以也许某种移动语义可以在这里工作?
如果QMap::insert
支持移动语义,并且QVector
是可移动构造的,就像它们的标准库对应物一样,那么你确实可以将向量移动到地图中。但移动空矢量与复制一样快。
如果QMap
有类似emplace
函数的std::map
,那么您甚至可以在没有移动的情况下就地构建向量。
我不熟悉Qt,但您需要从文档中验证这些详细信息。 Qt是否支持移动语义并不能改变手动内存管理是一种痛苦的事实。
修改:根据documentation QVector
似乎是可移动的,但QMap
不支持移动语义。但是,正如Arpegius和文档指出的那样,QVector
进行了写时复制优化,因此只要未复制复制的向量,就不会复制数据。复制空载体时,这一切都不重要。
再次编辑
如果添加的向量充满了数据,那么复制确实非常昂贵,除非它保持不变。移动可以解决这个问题,但QMap
似乎不支持这一点。但是还有另一个技巧:插入一个空向量,然后swap
完整的向量与地图中的空向量。
答案 1 :(得分:1)
最简单,最常用的方法是:
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上同样运行良好:)
这样您就可以处理已经在地图中的矢量。矢量本身永远不会被复制。向量的成员被复制,但它们是隐式共享的,因此复制实际上是指针复制和原子引用计数增量。