void*作为通用引用类型是如何工作的



《编程语言语用学》,Scott 著

用于系统编程,或便于编写通用容器(集合)对象(列表、堆栈、,队列、集合等),其中包含对其他对象的引用语言提供了一种通用的引用类型在C和C++中类型称为void*。在Clu中,它被称为any;在模块a-2中,住址在模块-3中,参考文献;在Java中,Object;在C#中,对象。

在C和C++中,void *如何作为通用引用类型工作?

void *始终只是一个指针类型,而通用引用类型包含所有值,包括指针和非指针。所以我看不出void *是一个通用的引用类型。

谢谢。

void*指针通常会包含指向成员的任何非C++指针。这在实践中相当不方便,因为在使用它之前,您需要将它强制转换为另一个指针类型。您还需要将它转换为从转换为的相同指针类型,以生成void*,否则您将面临未定义行为的风险。

qsort函数就是一个很好的例子。它以void*指针作为参数,这意味着它可以指向任何东西的数组。传递给qsort的比较函数必须知道如何将两个void*指针强制转换回数组元素的类型,以便对它们进行比较。

您混淆的关键是,无论是void *的实例,还是Modula-3的refany的实例,或者任何其他语言的"可以引用任何东西"类型的实例,都包含它所引用的对象。void *类型的变量始终是指针,refany类型的变量总是引用。但是他们引用的对象可以是任何类型。

编程语言理论的纯粹主义者会告诉你,C根本没有引用,因为指针不是引用。它有一个几乎通用的指针类型void *,可以指向任何类型的object(包括整数、聚合和其他指针)。作为一个常见但并不普遍的扩展,它也可以指向任何函数(函数不是对象)。

纯粹主义者还会告诉你,C++不具有(几乎-)通用指针类型,因为它的类型系统更严格,而且也没有通用引用类型。

他们还会说,你正在读的书在术语上很草率,他们会提醒你不要把任何一本这样的书视为关于术语问题或任何其他问题的福音真理。相反,你应该广泛阅读书籍、CS期刊和会议记录(统称为"文献"),直到你对术语、分支学科或实践社区的具体内容等达成共识

最后,它们会提醒你,C和C++是两种不同的语言,任何同时谈论它们的人要么在掩盖区别(在上下文中可能相关,也可能不相关),要么已经过时了几十年,要么两者兼而有之。

原因可能是您可以获取任何类型的任何变量的地址并将其强制转换为void*

它通过一个静默契约来确定对象的实际类型。

因此,您可以将不同类型的元素存储在一个容器中,但在取回元素时,您需要以某种方式知道什么是什么,才能正确地解释它们。

void*提供的唯一便利是它是惯用的,即很明显,取消引用指针是没有意义的,并且void*可以隐式转换为任何指针类型。那是给c/的

在c++中,这被称为首选类型擦除技术。或者特殊类型,比如any(也有增强版)

void*不再只是一个指针。因此,它保存对象的地址(或数组和类似的填充)

当你的程序运行时,每个变量都应该在内存中拥有自己的地址,对吧?指针是指向那个地址的东西。

例如,在正常情况下,每种类型的指针都应该是相同类型的对象int b = 5; int* p = &b;。但在这种情况下,你知道类型是什么,它意味着specific type

但有时,你只想知道它在记忆中的某个地方存储了一些东西,你知道这个地址的"类型"是什么,你可以很容易地铸造。例如,在我正在学习的OpenCV库中,有很多函数,用户可以将参数传递到其中,而不是声明全局变量,并且在callback函数中最常用,如下所示:void onChange(int v, void *ptr)这里,库并不关心ptr指向什么,它只知道当您调用函数时,如果您将地址传递给类似的onChange(5,&b),那么在处理它之前,必须将ptr强制转换为相同的类型int b = static_cast<int*>(ptr);

理解Richard Reese的指针可能会对有所帮助

指向void的指针是一个通用指针,用于保存对任何数据类型的引用。

它有两个有趣的属性:

  • 指向void的指针将与指向char 的指针具有相同的表示和内存对齐方式

  • 指向void的指针永远不会等于另一个指针。但是,分配了NULL值的两个空指针将是相等的。

任何指针都可以分配给指向void的指针。然后可以将其强制转换回其原始指针类型。当这种情况发生时,该值将等于原始指针值。

这在以下序列中进行了说明,其中指向int被分配给指向void的指针,然后返回到指向int 的指针

#include<stdio.h>
void main()
{
int num = 100;
int *pi = &num;
printf("value of pi is %pn", pi);
void* pv = pi;
pi = (int*)pv;
printf("value of pi is %pn", pi);
}

指向void的指针用于数据指针,而不是函数指针

最新更新