【问题标题】:A packet reader Qt/C++ API design一个数据包阅读器 Qt/C++ API 设计
【发布时间】:2012-07-10 08:16:05
【问题描述】:

我有一个二进制数据包格式,我必须为其实现一个 C++ 阅读器。该库使用 Qt 4,数据包源可以是任何 QIODevice,例如 QTcpSocket、QFile 或 QBuffer。格式包括数据包格式,每个数据包内部也可能有很多子结构。我需要读者返回以下内容:

  • 包头;
  • 子结构数组;
  • 读取操作的错误状态 - 成功、错误或数据不足(尤其是从套接字或其他类型的缓冲设备读取时)。

阅读器 API 有多种可能的方法:

  1. Packet read(Status &status); - 按值返回,通过引用参数返回错误状态。
  2. Packet *read(bool *ok); - 出错时返回 NULL,或者如果数据不足,则根据情况将 true 或 false 写入 ok 变量(如果不是 NULL)。
  3. Packet *read(); - 在错误或数据不足时返回 NULL,调用另一个方法 bool wasError(); 来检查发生了什么。通过使ok 参数具有默认值NULL,可以将这个与前一个合并。
  4. Status read(Packet &packet); - 如果返回状态为Ok,则将读取的值放入packet 变量中,否则表示错误或EOF。
  5. Packet read(); - 按值返回,在 EOF 或错误的情况下返回一个特殊的“空包”值。致电wasError() 确定发生了什么。

当然,还有其他可能的组合。似乎没有最好的选择。方法 1、2 和 4 要求调用者声明一个单独的变量来存储结果。方法 2 和 3 涉及弄乱堆,出于明显的原因,我不想这样做。方法 1 并没有明确说明发生错误时返回的内容。方法 5 解决了这个问题,但在数据包结构中引入了一个特殊的“null”标志,尽管它可能不属于那里。

我可以采用第 5 种方法,但会返回一个包含数据包和状态信息的特殊结构,但这会引入另一种“合成”类型,并且仍然会留下一个问题“如果出现错误,数据包字段将包含什么? "

或者我可以采用第三种方法并返回QSharedPointer<Packet>,因此调用者不必手动处理堆。但是对于 Pimpl 而言,Packet 结构可能已经是一种智能指针(共享类)。也许我可以改用那个内部指针并引入一个isNull() 方法,就像 QString 一样。

有没有更好或传统的方法?

【问题讨论】:

  • 我可能会提供一些答案,但我知道我必须考虑清楚。这不是简单的回答,其他取决于格式、行为、系统设计。

标签: c++ api qt


【解决方案1】:

好吧,我已经按照以下方式实现了它。

读取方法的签名是:

Packet readPacket(bool *error = NULL);

Packet 类如下所示:

class Packet {
    inline Packet(): p(NULL) {} // this is returned on error or EOF
    Packet(const Header &header, const Data &data);
    inline bool isNull() {return p == NULL;}
private:
    QSharedDataPointer<PacketPrivate> p;
};

数据包阅读器还有bool wasError() 方法用于检索错误状态,以防error 参数未提供给readPacket() 函数。

这个实现允许我:

  1. 创建优雅的循环,如while (!(packet = reader-&gt;readPacket()).isNull()) ...
  2. 为了避免在 Packet 类中出现“error”或“null”等不相关的字段。
  3. 为了避免手动分配或删除指针,或者不得不在调用方显式处理智能指针。
  4. 为了避免在使用默认构造函数时出现未初始化的字段。

它仍然远非完美,因为需要提供error 参数或稍后调用wasError()。但我相信强制调用者检查错误的唯一方法是使用异常,但出于可移植性的原因我不想这样做。

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多