void实际上不是特定类型。那么系统如何确定内存块的结束从而加密数据块的值?如果你知道内存中的数据,你肯定可以将类型从void更改为特定类型,但是当你不知道时?语言设计师制作这个概念的目的是什么?
答案 0 :(得分:1)
这主要用于C将数据传递给回调函数或构建通用容器。只要您想从具体数据类型中抽象出来,就会使用它。类型" void *"只是能够传递指针,有时候就是你所需要的。
但是你是对的,如果你想实际访问数据,你必须在某些时候将指针类型转换回具体的数据类型。所以一些代码必须实际记住类型(它必须正确,否则你只是阅读垃圾!)。但不是所有代码必须知道类型。有些功能可以将其称为" void *"因此更抽象:例如,然后可以使用链表来包含字符串或矩阵或任何您想要的内容,而无需为每种类型重新编写列表代码。
在C ++中,您可以通过在回调数据的情况下使用继承(接口)来避免可能不安全的转换,或者在容器的情况下使用模板。
顺便说一下。在C / C ++中,在很多情况下你实际上并不知道数据块的结尾,这对于" void *"并不是特别的。指针。这就是为什么有这么多危险的缓冲区溢出的原因。
答案 1 :(得分:1)
那么系统如何确定内存块的结尾从而加密数据块的值?
它不能。由您决定知道哪种类型,并适当地转换指针以访问它。
但是当你没有?
然后您无法使用void*
。
语言设计师制作这个概念的目的是什么?
它是来自C的宿醉,它是传递泛型类型的唯一方法。例如,qsort
库函数使用它将指向任意类型的指针传递给用户提供的比较函数;它取决于用户知道真实类型是什么,并将指针强制转换以执行比较。
在C ++中,它没有什么用处 - 有更可靠的方法(包括模板和基于继承的多态)来支持泛型类型。例如,等效的std::sort
是一个模板,并在整个过程中保留正确的类型。
答案 2 :(得分:0)
至于我的经验,我会说它就像一个小丑,它允许你在不知道指针类型的情况下传递指向函数的指针。例如,在C中,链表的“通用”实现将有一个指向数据的void *指针,允许添加多种数据类型
答案 3 :(得分:0)
它用作占位符。最终,指针将被传递给一个确实知道实际类型的函数。
一个例子是通用排序功能。它需要一个数组,它可以包含任何类型(因此这是void*
)和比较函数。比较函数应该适合于数组的类型,因此它会在取消引用值之前将void*
指针强制转换为正确的type*
。
这主要是C语言的延续。在C ++中,为此使用模板很常见。