C ++取消引用void指针,将int ptr转换为void ptr

时间:2013-05-30 07:12:12

标签: c++ pointers void

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

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

语法错误:

  

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

我知道:

  1. 任何指针类型都可以存储在void指针类型中,而无需显式转换
  2. 解除引用尝试无效指针是语法错误
  3. 但如果我们不能做#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
    

6 个答案:

答案 0 :(得分: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);

  /*  ... */
}

答案 1 :(得分:4)

void*可以指向任何东西,因此分配任何指针都非常好。

但是因为它可能指向任何东西,所以取消引用它是不可能的:编译器不知道它指向哪个对象类型,因此它无法生成代码来执行正确的事情,具体取决于对象的类型。

答案 2 :(得分:3)

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

void *指针最适合用于与相当低级别的东西(例如I / O驱动程序)接口,在那里你很少关心你正在处理的数据,你只知道你有一个缓冲区和大小。

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

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

这将不会出现编译器错误或警告。这完全有效。但它不太可能达到你的期望

答案 3 :(得分:2)

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

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

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

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

我确实要将int指针存储到void *指针。 在那种情况下,您可能会收到警告,例如“从不同大小的整数转换为指针”。为此您首先需要指定一些与整数相关的内存void指针,然后使用该void指针可能如下,

void *ptr = malloc(sizeof(int));
*((int*)ptr) = 5;
printf("%d\n",*((int*)ptr));