什么是C ++中的void指针?

时间:2010-05-18 19:55:34

标签: c++ pointers

我的问题很简单: C ++中的void指针是什么?(使用void* myptr;声明的那些内容)

他们的用途是什么?我可以让它们指向任何类型的变量吗?

13 个答案:

答案 0 :(得分:20)

基本上是来自C的残余。

  

它们的用途是什么?

在C中,它们被广泛使用,但是在C ++中,我认为它们很少需要,因为我们有多态性,模板等,它们提供了一种更清洁,更安全的方法来解决同样的问题。在C中,我会使用void指针。

  

我可以让它们指向任何类型的变量吗?

是。但是,正如其他人所指出的那样,你不能直接使用void指针 - 你必须先将它转换为指向具体数据类型的指针。

答案 1 :(得分:7)

是的,这是一个C构造(不是C ++特定的),它允许您声明指向任何类型的指针变量。除了将它转换回它实际指向的真实对象之外,你不能用这样的指针做任何事情。在现代C ++中,void *几乎已经过时了,在很多情况下会产生基于模板的通用代码。

答案 2 :(得分:6)

关于C ++中void指针存在的少数用法之一是它们用于重载new运算符。根据定义,所有new运算符都返回类型void*。除此之外,其他人所说的是真的。

答案 3 :(得分:4)

来自cplusplus.com

  

指针的void类型是特殊的   指针类型。在C ++中,无效   表示没有类型,所以   void指针是指向的指针   到没有类型的值(因此   也是一个不确定的长度和   未定的解引用属性)。

     

这允许void指针指向   任何数据类型,来自整数值   或浮点到一串字符。   但作为交换,他们有一个伟大的   限制:他们指出的数据   不能直接解除引用(哪个   是合乎逻辑的,因为我们没有类型   解除引用,因此   我们将永远不得不施展   在一些虚拟指针中的地址   指向a的其他指针类型   以前的具体数据类型   解除引用它。

答案 4 :(得分:4)

键入隐藏。它在现代C ++中仍然有其有效用途。深入了解一下boost中的源代码,你会发现一些。一般来说,空洞*的使用深埋在更复杂的构造的内部,确保界面的类型安全,同时在内部进行黑魔法。

答案 5 :(得分:3)

他们在C中做过一次执行指向任何东西的工作,这是一个传递给库的指针,他们以userdata的形式回馈给你。如果没有程序员以某种方式知道它们的上下文,那么void *根本没用,因为你不知道另一端是什么,你不能对数据做任何事情。除了将指针传递给其他知道的代码。

我不明白为什么人们不仅仅使用未定义的类型,即不透明的指针。输入安全性,用户数据。

在现代C ++中,指向void的指针几乎完全被多态和模板生成的通用代码所取代。但是,您可能仍需要使用它们与本机C代码进行交互。要在任何给定的上下文中安全地使用void *,只能将一种类型转换为void *。这样,你肯定知道它指向的是什么。如果您需要更多类型,可以快速完成 struct safevoidptr { base* ptr };
struct safevoidptr { void* ptr; int type; };
我相信dynamic_cast也可以将void *转换为多态类型,虽然我从未使用过dynamic_cast,所以不要相信我的话。

答案 6 :(得分:1)

void指针可以指向任何东西,只要它的内存: - )

C标准规定您可以将任何指针转换为void-pointer,然后将其转换回来而不会丢失任何内容。

答案 7 :(得分:1)

指向void的指针是与汇编语言指针最接近的概念。它是一个通用指针,为某些东西(函数或数据)的地址或位置保留空间。正如其他人所说的那样,它必须在被解除引用之前进行投射。

void指针是一种用于在C语言中表示Object Orient概念的流行工具。 void指针的一个问题是内容可能与接收者的感知不匹配。如果调用者将指针设置为指向一个正方形,但是接收函数期望指向一个cat的指针,则指针被转换时会发生未定义和奇怪的事情。

答案 8 :(得分:1)

由于已经有这么多好的答案,我只提供一个比较常见的答案:模板专业化。如果我没有错误地回想起来,Stroustrup书中有一个例子:将矢量专门化为矢量,然后使用矢量从矢量派生(私下)。这样,向量将只包含简单易用的内联代码(即从向量调用相关函数)。这将减少在使用多种不同类型的指针的程序中编译向量时的重复次数。

答案 9 :(得分:0)

void ptr基本上是一个空盒子。用你想要的任何东西填充它,但要确保你标记它(tupecasting)

答案 10 :(得分:0)

我在动态列表中使用它们来容纳更多类型的对象(都是指针) typedef void* Object; 然后,当您声明一个Object变量时,您可以在其中存储任何指针。 根据需要,它或多或少都有用 当你必须在任何地方存储任何指针时,我发现它非常有用,你不能只从一个派生所有类。除此之外,其他人说使用模板,polimorphism等更好。

答案 11 :(得分:0)

你可以在C中用void做的事情,但不能用C ++做的事情:

void *会自动转换为其他指针类型。 (你知道它是一个空洞* - 你没有因强迫显式演员而获得类型安全性)

Struct* p = malloc( sizeof(Struct) );
// vs C++
Struct* p = (Struct*)malloc( sizeof(Struct) );
// Some will argue that that cast style is deprecated too, and c++ programmers 
// need to actually do this:
Struct* p = reinterpret_cast<Struct*>malloc( sizeof(Struct) );
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure
// you know what you are doing!

void *也在C中进行了间接计数,在将指针传递给指向指针的函数时允许更高的安全性。

void funcInitializingOutPtr( void** ppOut)
{
  *ppOut = malloc( x );
}

int* out = NULL;
funcInitializingPtr(out);  // C would signal this as an error
funcInitializingPtr(&out); // correct
// vs C++ 
funcInitializingPtr( (void**)&out ); // so much safer needing that exlicit cast.
funcInitializingPtr( (void**)out);   // oops. thanks C++ for hiding the common error

答案 12 :(得分:0)

我相信无效*是您可以进行类型转换/存储任何内容的内存位置。我的一些语言专家会对我不同意这一点。但我在我的许多项目中成功地使用了它。

我看到的唯一问题是类型安全