3

这些代码行显示以下错误:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; 
cout << *vPtr; 

语法错误:

`void*' 不是指向对象的指针类型

我知道:

  1. 任何指针类型都可以存储为 void 指针类型,无需显式强制转换
  2. 取消引用 void 指针的尝试是语法错误

但是如果我们不能做到第 2 点,那么第 1 点除了语法正确还有什么用?我想e使用 .. 打印 5(即此处)vPtr,这可能吗?

这工作正常:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; //specific to generic Ok!
double * dPtr = (double *)vPtr; //to let compiler know stoarge size
cout << *dPtr; //indirectly it is vPtr i.e. a void ptr, can be deref only if cast
4

6 回答 6

5

要引用void*指针,您需要将指针转换回兼容的类型。

void*指针在 C 中经常使用,但是,由于在 C++ 中我们可以进行函数重载和多态,因此它们的使用受到了更多限制。

在 C 中使用指针的一个很好的例子是void*使用回调的函数:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                   void *(*start_routine) (void *), void *arg);

当您调用 pthread_create 函数时,它会start_routine回调您。在这种情况下,您可能希望将一些数据传递给您的start_routine. 由于线程库无法为您可能想要传递给回调的每种类型声明 pthread_create 函数,void*因此使用该类型。

void myCallBack(void* arg) {
   int* value = (int*)arg;

   /* Do something with value: it is an int* now*/
   printf("Message from callback %d\n", *value);
}


/* Some main function or whatever... */
{ 
  /*  ... */
  int foo = 123;
  ret = pthread_create(&thread, &attr,myCallBack, &foo);

  /*  ... */
}
于 2013-05-30T07:18:38.653 回答
4

void*可以指向任何东西,因此为它分配任何指针都很好。

但是因为它可能指向任何东西,所以取消引用是不可能的:编译器不知道它指向的对象类型,所以它不能根据对象的类型生成代码来做正确的事情。

于 2013-05-30T07:16:32.270 回答
3

您不能取消引用它,因为编译器不知道它是什么。您必须将其转换为适当的类型(并且编译器必须假设您知道自己在做什么)。

void *指针最适合用于与相当低级别的东西(例如 I/O 驱动程序)交互的地方,在这种情况下,您几乎不关心正在处理的数据,您只知道您有一个缓冲区和一个大小。

任何其他用途都充满危险。例如

int i = 5;
void *p = &i;
.....
float *f = (float *)p;

这不会得到编译器错误或警告。这是完全有效的。但它不太可能做你所期望的

于 2013-05-30T07:22:33.953 回答
2

存储一个指针并对它的类型保持无关紧要是很有用的。这就是 void* 的用途。这是在纯 C 中设计存储容器(链表、哈希映射)时可以采用的一种方法。

如果您想使用指针,那么您必须跟踪它的类型以及它的值,因为您不能任意引用指针,并且当您转换为 void* 时所有类型信息都会丢失。

在您的示例中,您可以使用带有 void* 和类型字段的简单结构。

在 C++ 中,您可以使用多态结构甚至模板来实现这些目标:您所做的更像是 C 风格。

于 2013-05-30T07:18:23.780 回答
1

如果不进行类型转换,您将无法e在此处打印。void*指针不仅仅是一个存储地址的简单变量,它还有一个类型,它告诉编译器它应该使用该地址读取多少大小。A void*,因为它不具有任何类型,所以不能在没有类型转换的情况下取消引用。通过类型转换,您可以告诉编译器应该从指针携带的地址开始读取多少字节。

void*为程序员提供了一种轻松存储和使用其他类型指针的简便方法。我们不能使用unsigned int或类似的方法来存储指针的值,因为指针的大小取决于处理器。此外,我们可以使用void*使函数的指针参数/返回值更通用。

于 2013-05-30T07:18:25.410 回答
0

我的事情是你想将 int 指针存储到 void* 指针。在这种情况下,您可能会收到类似“从不同大小的整数转换为指针”的警告。为此,您首先需要分配一些与整数相关的内存 void 指针,然后使用该 void 指针可能如下所示,

void *ptr = malloc(sizeof(int));
*((int*)ptr) = 5;
printf("%d\n",*((int*)ptr));
于 2013-05-30T07:33:34.847 回答