假设我们有一个功能商店
void store(const QByteArray& data);
该功能的工作是获取数据并将其存储起来.不幸的是,如果参数是使用QByteArray :: fromRawData(ptr,size)创建的,那么这样做是不安全的,因为它及其所有副本都要求ptr保持有效.
因此,store没有选项禁止其调用者传入这样的数组,将数据视为立体声中的const char *或强制使用detach强制复制.所有这一切都不令人满意,特别是后者会损害性能,因为如果数据在传递给商店之前被COW复制,我们将进行不必要的深层复制.
QByteArray有一个私有函数nulTerminated,其实现似乎正是我想要的:如果它不拥有内存,它就是深拷贝.如果它拥有内存,它只会返回*这个.
真的有两个问题
>是否有使用公共设施的解决方法?
> Qt文档提到ptr只能在返回值及其任何副本的生命周期内存活.如果你说.right(.size()),它似乎不是副本,所以Qt需要根据文档制作一份深层副本.但它真的这样做了吗?
最佳答案 查看源(例如
here),ba.right(ba.size());实际上是简单的浅拷贝,几乎是无操作,所以这不是你的解决方案.在任何情况下,依赖于没有文档支持的任何行为都有点不安全,在未来的Qt版本中可能会在没有通知的情况下进行更改.
话虽如此,QByteArray::detach()
没有证件,但公开.它将对使用fromRawData()创建的数组执行深层复制,但不会对已经未共享的数据执行深度复制,我认为这不太可能改变.示范:
QByteArray ba1 = QByteArray::fromRawData("foo", 4);
QByteArray ba2("foo");
qDebug() << (void*)ba1.constData() << (void*)ba2.constData();
ba1.detach(); ba2.detach();
qDebug() << (void*)ba1.constData() << (void*)ba2.constData();
以上输出例如:
0x804b960 0x93ebfd8
0x93d2170 0x93ebfd8
查看源代码,IS_RAW_DATA
macro位于qbytearray.cpp文件中,我没有发现任何可以使用公共接口利用它的方法.所以,做你想做的事似乎是不可能的,而detach()是你能得到的最接近的,即使QByteArray :: squeeze()也不会分离原始数据.