void* 或 char* 用于通用缓冲区表示?
我正在设计一个 Buffer 类,其目的是表示一块内存。
我的底层缓冲区是一个 char*
(实际上是一个 boost::shared_array
,但这并不重要)。
我一直在决定为我的构造函数选择什么原型:
我应该选择:
Buffer(const void* buf, size_t buflen);
还是选择:
Buffer(const char* buf, size_t buflen);
或者其他?
通常会做什么,为什么?
I'm designing a Buffer class whose purpose is to represent a chunk of memory.
My underlying buffer is a char*
(well, a boost::shared_array<char>
actually, but it doesn't really matter).
I'm stuck at deciding what prototype to choose for my constructor:
Should I go with:
Buffer(const void* buf, size_t buflen);
Or with:
Buffer(const char* buf, size_t buflen);
Or something else ?
What is usually done, and why ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于构造函数和其他 API 函数,
void*
的优点是它允许调用者传入任何类型的指针,而不必进行不必要的强制转换。如果调用者能够传入任何类型是有意义的,那么void*
是更好的选择。如果确实只有调用者能够传入 char* 才有意义,则使用该类型。For the constructor and other API functions, the advantage of
void*
is that it allows the caller to pass in a pointer to any type without having to do an unnecessary cast. If it makes sense for the caller to be able to pass in any type, thenvoid*
is preferable. If it really only makes sense for the caller to be able to pass inchar*
, then use that type.如果buffer是void*类型,string是char*类型,API接口对用户来说会更清晰。比较 memcpy 和 strcpy 函数定义。
API interface is more clear for user, if buffer has void* type, and string has char* type. Compare memcpy and strcpy function definitions.
C++17
C++17 引入了
std ::byte
专门为此。它的定义实际上很简单:
enum class byte : unsigned char {};
。我通常使用
unsigned char
作为底层结构(不希望符号弄乱我的缓冲区,因为我知道原因)。不过,我通常对其进行类型定义:然后将其称为
byte*
,它巧妙地传达了我认为的含义,比char*
或至少void*
。C++17
C++17 introduced
std::byte
specifically for this.Its definition is actually simple:
enum class byte : unsigned char {};
.I generally used
unsigned char
as the underlying structure (don't want signedness to mess up with my buffer for I know what reason). However I usually typedefed it:And then refer to it as
byte*
which neatly conveys the meaning in my opinion, better than eitherchar*
orvoid*
at least.我更喜欢
char*
,因为对我个人而言,它作为“缓冲区”效果更好。void*
看起来更像是“一个指向我不知道什么的指针”。此外,无论如何,这就是你的基础。I'd prefer
char*
, because for me personally it plays better with being "a buffer".void*
seems more like "a pointer to I don't know what". Besides, it is what your underlying is, anyway.我推荐 uint8_t,它在 stdint.h 中定义。它基本上与“typedef unsigned char byte;”相同。其他人一直推荐的,但它的优点是成为 C 标准的一部分。
至于 void*,我只会将其用于多态性。 IE。如果我还不知道某个东西指向什么类型,我只会将其称为空指针。在您的情况下,您有一个字节数组,因此我将使用 uint8_t* 作为类型来标记它。
I'd recommend uint8_t, which is defined in stdint.h. It's basically the same thing as the "typedef unsigned char byte;" that others have been recommending, but it has the advantage of being part of the C standard.
As for void*, I would only use that for polymorphism. ie. I'd only call something a void pointer if I didn't yet know what type of thing it would be pointing to. In your case you've got an array of bytes, so I'd label it as such by using uint8_t* as the type.
我更喜欢使用
unsigned char *
或uint8_t *
来实现缓冲区,因为void *
有一个恼人的限制,即您无法对其执行指针数学运算。因此,如果您想在距缓冲区的某个偏移量处处理一些数据,或者只是将缓冲区分成块或其他什么,无论如何,您都必须转换为其他类型来进行数学计算。我更喜欢
unsigned char *
或uint8_t *
而不是普通的char *
因为 关于别名和char *
的特殊规则,这可能会严重影响缓冲区上运行的某些循环。I prefer
unsigned char *
oruint8_t *
for buffer implementations, sincevoid *
has the annoying restriction that you can't perform pointer math on it. So if you want to process some data at some offset from the buffer, or just break your buffer up into chunks or whatever, you are stuck casting to some other type anyway to do the math.I prefer
unsigned char *
oruint8_t *
over plainchar *
because of the special rules regarding aliasing andchar *
, which has the potential to seriously pessimize some loops working on your buffers.