10

我想编写一个函数,其中 QByteArray 被输入到函数中。我想从接收数据中删除一些标头并将其存储到全局 QByteArray 中。

void abc::CopyData(const QByteArray &data)
{
    switch(RequestPacketCount)
    {
        case REQUEST_FIRST_PACKET:
        {
            ByteArrayData = data;
        }
            break;
        case REQUEST_SECOND_PACKET:
        case REQUEST_THIRD_PACKET:
            ByteArrayData.append(data);
    }
}

我想删除'n' no。从“数据”开始的字节并将剩余数据存储到“ByteArrayData”中

提前致谢。

4

3 回答 3

7

您似乎想要的只是复制原始数组并使用remove

ByteArrayData = data;
ByteArrayData.remove(0, n);            // Removes first n bytes of ByteArrayData,
                                       // leaving data unchanged

由于 QByteArray 是隐式共享的,因此副本的构建需要恒定的时间,而修改(删除)将在需要时生成实际副本。

为了有效地追加,您可以只使用数据来获取字节数组,然后追加您想要的部分。这将防止不必要的临时对象。那看起来像;

ByteArrayData.append(data.data() + n, data.size() - n);
于 2014-03-19T05:29:06.380 回答
2

您可以使用QByteArray::mid

ByteArrayData = data.mid(n);
//...
ByteArrayData.append(data.mid(n));
于 2014-03-19T07:06:32.627 回答
0

添加到 Joachim 的答案中,在 C++ 中,一些实现细节泄漏到接口中是相当不幸的,但出于性能原因,仍然首选让编译器通过将参数作为值传递来进行复制。因此,解释一下,最好的解决方案是:

void abc::CopyData(QByteArray data)
{
  ...
  data.remove(0, n);
  ...
  ByteArrayData.append(data);
}

您绝对不希望通过值传递此类参数的唯一地方是信号声明 - 信号永远不会修改它们的数据。但是,插槽可以这样做:

class MyClass : public QObject {
  Q_OBJECT
  ...
public:
  // pass by const reference in signals
  Q_SIGNAL void dataSource(const QByteArray &); // The only correct signal form
  // pass by const reference or value in slots, depending on use
  Q_SLOT void dataSink1(const QByteArray &); // Valid
  Q_SLOT void dataSink2(QByteArray); // Valid as well.
};

无论是 Qt4 还是 Qt5 连接样式,连接到任一插槽都使用相同的代码。因此,您不必担心由于泄漏的实现细节会破坏您的代码而导致的此类接口更改。

// Qt4 - you should elide const and reference anyway
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink1(QByteArray));
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink2(QByteArray));
// Qt5
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink1);
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink2);
于 2014-03-19T15:29:08.573 回答