void* myptr;
声明的东西)。它们有什么用处?我能让它们指向任何类型的变量吗?
基本上,这是从 C 语言遗留下来的。
它们有什么用处?
在 C 中,它们被广泛使用,但在 C++ 中,我认为它们很少需要(如果需要的话),因为我们有多态、模板等功能,这些功能提供了更清晰、更安全的方式来解决在 C 中需要使用空指针的问题。
我可以让它们指向任何类型的变量吗?
可以。然而,正如其他人所指出的那样,你不能直接使用空指针 - 你必须首先将其转换为一个具体数据类型的指针。
是的,这是一种C语言结构(不是仅限于C++),允许您声明一个指向任何类型的指针变量。您实际上不能对这样的指针做太多事情,除非将其强制转换为它实际指向的真正对象。在现代C++中,void* 已经基本过时了,在许多情况下被基于模板的通用代码所取代。
在C++中,void指针的少数用途之一是对new
操作符进行重载。所有new
操作符的返回类型均为void*
。除此之外,其他人所说的都是正确的。
指针的void类型是一种特殊类型的指针。在C++中,void表示没有类型,因此void指针是指向没有类型(因此也具有未确定长度和未确定解引用属性)的值的指针。
这使得void指针可以指向任何数据类型,从整数值或浮点数到字符字符串。但是,它们有一个很大的限制:它们指向的数据不能直接进行解引用(这是合理的,因为我们没有类型可以解引用),因此我们将始终不得不将void指针中的地址转换为指向具体数据类型的其他指针类型,然后才能对其进行解引用。
类型隐藏。在现代C++中,它仍然具有有效的用途。挖掘一下Boost中的源代码,你会发现一些用法。通常情况下,void*的使用被深深地嵌入到更复杂的结构中,这些结构可以确保接口的类型安全,并在内部进行黑魔法。
struct safevoidptr {
base* ptr
};
struct safevoidptr { void* ptr; int type; };
void
指针是最接近汇编语言指针的概念。它是一种通用指针,为地址或某个东西(函数或数据)的位置保留空间。正如其他人所说,必须在对其进行解引用之前将其强制转换。
void
指针是在C语言中表示面向对象概念的流行工具。void指针的一个问题是内容可能与接收方的感知不匹配。如果调用者将指针设置为指向正方形,但接收函数期望指向猫的指针,则在进行强制转换时会发生未定义和奇怪的事情。
由于已经有很多好的答案,我只提供其中一个比较常见的:模板特化。如果我没有记错的话,Stroustrup的书中有一个例子:将vector作为vector进行特化,然后让vector从vector派生(私有)。这样,vector将只包含直接易于内联的代码(即从vector调用相关函数)。这将减少在使用许多不同类型指针的程序中编译vector时的重复数量。
在 C 中可以使用 void,但在 C++ 中不能做的事情:
void* 会自动转换为其他指针类型。 (你知道它是一个 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!
在C语言中,void*也可以进行间接计数,这使得在将指针传递给需要指向指针的函数时更加安全。
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
void*
几乎总是不正确的。为什么不通过寻找正确的处理方式来提高您的C++技能呢? - Tyler McHenryvoid*
进行比较,这只是说明了这种语言特性可能会带来多大的麻烦。 - Steven Sudit