【问题标题】:Remove first bytes from QByteArray从 QByteArray 中删除第一个字节
【发布时间】:2014-04-25 04:05:41
【问题描述】:

我想写一个函数,其中 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。从'data'开始的字节并将剩余数据存储到'ByteArrayData'

提前致谢。

【问题讨论】:

    标签: qt qbytearray


    【解决方案1】:

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

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

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

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

    ByteArrayData.append(data.data() + n, data.size() - n);
    

    【讨论】:

    • 谢谢,但我收到以下错误,错误:将 'const QByteArray' 作为 'QByteArray& QByteArray::remove(int, int)' 的 'this' 参数传递会丢弃限定符 [-fpermissive]
    • @beparas 啊,真的,我错过了const。我会更新的。
    • 谢谢,append() 函数呢。
    • @beparas 您的意思是要将数据中除前 n 个字节之外的所有字节追加到 ByteArrayData?
    • 我的 CopyData() 函数调用了 3 次,每次 'data' 具有 'n' 字节的修复标头,您的解决方案适用于案例 1 :),但是如何附加数据(删除标头)在上述代码中的第 2 和第 3 情况下。谢谢
    【解决方案2】:

    你可以使用QByteArray::mid:

    ByteArrayData = data.mid(n);
    //...
    ByteArrayData.append(data.mid(n));
    

    【讨论】:

      【解决方案3】:

      除了 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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多