我有一些包含不同数字类型字段的字节字段。然后传递这些字段的指针并作为成员存储在其他类中。
我应该使用char*
或void*
作为指针类型吗?
目前,我认为char*
只有一个优势:您无法取消引用void*
。当从字段中读取值时,这不是问题,因为我必须转换为相应的指针类型。如果我想逐字节地对字段进行简单复制,我首先需要将void*
强制转换为char*
,因此直接将其存储为{{char*
会更容易。 1}}。
或者是否有任何理由反对使用char*
?
通常,我宁愿保持尽可能低的级别,因为我必须将字段传递给其他低级接口。
答案 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 ++标准定义了三种不同的类型:
如果您加入#include <limits.h>
,则可以查看CHAR_MIN
:
char
为无符号 那么,这一切意味着什么?
您应该以某种方式存储字节,这样您就可以在不进行额外检查的情况下读取/写入其值。您可能希望您的字节为无符号值,因此请定义新类型(many high-level languages):
typedef unsigned char Byte;
然后,将指针定义为:
Byte* data_pointer;
然后,如果你的函数期望'void *'或'Byte *',则不需要做任何事情。但是,如果他们希望指向特定数字类型(int
,float
等),则需要reinterpret_cast
。
答案 2 :(得分:0)
非常简单且资源不足是类型指针的简单联合,因为据我所知,实际类型是通过上下文来完成的。
在运行时动态的另一端有 Boost::Any