对C ++中的字节字段使用char *或void *或其他东西?

时间:2015-04-20 09:15:00

标签: c++

我有一些包含不同数字类型字段的字节字段。然后传递这些字段的指针并作为成员存储在其他类中。

我应该使用char*void*作为指针类型吗?

目前,我认为char*只有一个优势:您无法取消引用void*。当从字段中读取值时,这不是问题,因为我必须转换为相应的指针类型。如果我想逐字节地对字段进行简单复制,我首先需要将void*强制转换为char*,因此直接将其存储为{{char*会更容易。 1}}。

或者是否有任何理由反对使用char*

通常,我宁愿保持尽可能低的级别,因为我必须将字段传递给其他低级接口。

3 个答案:

答案 0 :(得分:5)

使用char *作为内存blob是“易于使用”(例如逐字节操作)但是阅读和理解代码非常糟糕(但是你仍然可以在各种API中看到它)。

如果您的数据只是一块内存,那么最好使用void *。

仅当您的数据是特定类型的数组(char,int,uint8_t,某些结构,...)时,才使用该类型的指针。

如果您需要将结构视为“字节数据”(例如计算哈希),您可以在内部将其视为“char *”(或uint8_t *或uint_32_t *或您需要的任何内容)。但是,如果您不需要特定的内存布局,公共API仍应无效。

关键是:如果你有一个使用void *的API,你可以提供任何类型的指针(这是一个哈希函数的点)。但是,如果使用char *,则始终需要reinterpret_cast。

答案 1 :(得分:2)

使用char会引发一些问题 - 这一切都取决于你想如何处理存储在这些指针后面的值。

问题是,byte通常被解释为无符号值。例如:UTF-8编码。它产生字节序列that can have different values, depending on encoded code point。如果我们使用signed类型,我们必须将值转换为无符号类型才能正确检查它们的值(大于U+007F的代码点总是转换为字节序列,其中所有字符串都设置了符号位到1)。

char是否已签名是依赖于实现的。事实上,C ++标准定义了三种不同的类型:

  • signed char
  • unsigned char

如果您加入#include <limits.h>,则可以查看CHAR_MIN

  • 如果定义为0,则char无符号
  • 如果定义为某个负值(通常为-128),则char 已签名

那么,这一切意味着什么?

您应该以某种方式存储字节,这样您就可以在不进行额外检查的情况下读取/写入其值。您可能希望您的字节为无符号值,因此请定义新类型(many high-level languages):

typedef unsigned char Byte;

然后,将指针定义为:

Byte* data_pointer;

然后,如果你的函数期望'void *'或'Byte *',则不需要做任何事情。但是,如果他们希望指向特定数字类型(intfloat等),则需要reinterpret_cast

答案 2 :(得分:0)

非常简单且资源不足是类型指针的简单联合,因为据我所知,实际类型是通过上下文来完成的。

在运行时动态的另一端有 Boost::Any