(C++/温索克)结构的包装替代品



我一直使用结构来打包和接收数据包,将它们转换为从主数据包类继承的类会得到什么吗? 是否有另一种"C++ish"的打包方式和由此获得的任何性能提升?

这是非常通用的,可能有多种解决方案可用。这与序列化主题有关,您所说的是一个简单的序列化模型,其中数据包包含可以直接加载到内存中的结构,反之亦然。我认为 C 和 C++ 在这种情况下很棒,因为它们允许您直接编写类似结构的东西来流式传输并轻松读回。在其他语言中,您可以实现字节对齐,或者应该序列化对象以便能够将它们写入流。

在某些情况下,您需要读取字符串流,如XML,SOAP 等。在某些应用程序中,您应该使用结构。在某些情况下,您需要将对象序列化为流。这要看情况。但我认为使用结构和指针比使用对象序列化更向前。

在您的情况下,我认为每个实体都有 2 个结构。沿连线或文件移动的结构,以及将实体实例保存在内存中的类。如果对对象使用二进制序列化,则可以仅使用一个类来发送、接收和保留实例。

数据建模

通常,C++类应考虑其建模数据中的冗余。 因此,如果数据包共享一些通用布局,则可以创建一个类来对该数据及其操作进行建模。 您可能会发现派生类来添加反映可能的数据包数据布局层次结构的其他数据成员很方便,但其他时候,使用不相关的类来反映数据包各部分的不同布局可能同样方便(特别是如果消息部分的长度或顺序可能有所不同)。

为了给出一个更清晰的例子,说明适合您的想法的最简单情况 - 如果您有一个标准数据包标头,其中包含记录 ID、以字节为单位的记录大小和序列 ID,您可以合理地将这些字段放入一个类中,并为每个不同的记录 ID 公开派生一个类。 基类可能具有成员函数来读取这些值,同时从网络字节顺序转换为本地字节顺序,检查序列 ID 根据需要递增等 - 派生类及其用户都可以访问所有这些内容。

运行时多态性

不过,您应该警惕虚拟成员 - 在几乎所有实现中,它们都会在您的对象中引入虚拟调度指针,这可能会阻止它们镜像网络数据包中的数据布局。 如果有理由需要运行时多态性(很容易,尤其是在读取数据包时),您可能会发现,拥有一个与非多态数据布局类的层次结构具有 1:1 对应关系的类的多态层次结构很有用,并且只包含一个指向内存中数据位置的指针。

性能

使用带有布局的类或结构故意镜像网络数据包可能会让您非常方便地就地在该内存上运行,信任编译器创建有效的代码来执行此操作。 编译器通常非常擅长这一点。

该访问的效率(速度)应完全不受用于对数据建模的类层次结构的影响。 所涉及的数据偏移量和对非虚函数的调用都将在编译时解决。

如果引入虚拟函数,您可能会看到性能下降,因为它们可以防止内联并需要额外的指针间接寻址,但您应该通过考虑在需要支持的布局特定操作之间切换的其他方式和频率来将其置于上下文中(例如,到处使用 switch (record_id)if (record_id == X) 或显式函数指针)。

最新更新