简体   繁体   English

void *或char *用于通用缓冲区表示?

[英]void* or char* for generic buffer representation?

I'm designing a Buffer class whose purpose is to represent a chunk of memory. 我正在设计一个Buffer类,其目的是代表一块内存。

My underlying buffer is a char* (well, a boost::shared_array<char> actually, but it doesn't really matter). 我的底层缓冲区是一个char* (嗯,实际上是boost::shared_array<char> ,但它并不重要)。

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 ? 通常做什么,为什么?

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. 对于构造函数和其他API函数, void*的优点是它允许调用者将指针传递给任何类型,而不必进行不必要的强制转换。 If it makes sense for the caller to be able to pass in any type, then void* is preferable. 如果调用者能够传递任何类型是有意义的,那么void*是优选的。 If it really only makes sense for the caller to be able to pass in char* , then use that type. 如果调用者能够传入char*真的有意义,那么使用该类型。

API interface is more clear for user, if buffer has void* type, and string has char* type. 如果缓冲区具有void *类型,并且string具有char *类型,则API接口对用户更清晰。 Compare memcpy and strcpy function definitions. 比较memcpy和strcpy函数定义。

C++17 C ++ 17

C++17 introduced std::byte specifically for this. C ++ 17专门为此引入了std::byte

Its definition is actually simple: enum class byte : unsigned char {}; 它的定义实际上很简单: 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). 我通常使用unsigned char作为底层结构(不希望签名搞乱我的缓冲区因为我知道是什么原因)。 However I usually typedefed it: 但是我经常输入它:

// C++11
using byte = unsigned char;

// C++98
typedef unsigned char byte;

And then refer to it as byte* which neatly conveys the meaning in my opinion, better than either char* or void* at least. 然后将其称为byte* ,它在我看来整齐地传达了含义,至少比char*void*更好。

I'd prefer char* , because for me personally it plays better with being "a buffer". 我更喜欢char* ,因为就我而言,它更适合作为“缓冲区”。 void* seems more like "a pointer to I don't know what". void*似乎更像是“指向我不知道的东西”。 Besides, it is what your underlying is, anyway. 此外,无论如何,这都是你的基础。

I'd recommend uint8_t, which is defined in stdint.h. 我推荐uint8_t,它在stdint.h中定义。 It's basically the same thing as the "typedef unsigned char byte;" 它与“typedef unsigned char byte”基本相同; that others have been recommending, but it has the advantage of being part of the C standard. 其他人一直在推荐,但它具有成为C标准一部分的优势。

As for void*, I would only use that for polymorphism. 至于void *,我只会将其用于多态。 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. 在你的情况下,你有一个字节数组,所以我通过使用uint8_t *作为类型来标记它。

I prefer unsigned char * or uint8_t * for buffer implementations, since void * has the annoying restriction that you can't perform pointer math on it. 我更喜欢unsigned char *uint8_t *用于缓冲区实现,因为void *有一个烦人的限制,你不能对它执行指针数学运算。 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 * or uint8_t * over plain char * because of the special rules regarding aliasing and char * , which has the potential to seriously pessimize some loops working on your buffers. 我更喜欢unsigned char *uint8_t * over plain char *因为有关别名和char *特殊规则 ,它有可能严重地使缓冲区上的某些循环变得悲观。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 分配char缓冲区以保存float的文本表示形式 - Allocating char buffer to hold textual representation for float 复制 std::vector<unsigned char> 使用 memcpy 取消 * 缓冲区 - copying std::vector<unsigned char> to void * buffer using memcpy 将unsigned char * buffer转换为可以接受参数的可调用void指针 - casting unsigned char * buffer to a callable void pointer that can take an argument c ++ - 如何正确重载运算符以从 __generic_buffer 进行隐式类型转换<void*>到 __generic_buffer<const void*> ? - c++ - how to properly overload operator to do implicit type cast from __generic_buffer<void*> to __generic_buffer<const void*>? 跨平台套接字发送,在Windows上的linux const char *上缓冲const void *,最好的处理方式? - Cross-platform socket send, buffer const void* on linux const char* on windows, best way to handle? 内存中的字符数组表示 - Char array representation in memory 将void(*)()转换为void(*)(unsigned char) - Convert void (*)() to void (*)(unsigned char) &#39;void(*)(const char *)&#39;到&#39;void(*)()&#39;[-fpermissive] - 'void (*)(const char*)' to 'void (*)()' [-fpermissive] 将双字的void *表示形式转换为wstring - Convert void* representation of a dword to wstring 向rocksdb写入缓冲区(void *) - Writing a buffer (void*) to rocksdb
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM