我正在努力理解什么是 void*
以及何时适当地使用它,是否存在我应该了解的潜在不良用途(指一些酷炫的东西,而不是错误的用法)。
我不理解如何以及为什么要使用 void*
。如果我理解正确,我需要将当前指针强制转换为 void*
,然后在想要使用它时将其转换回原始类型...?
这有什么好处吗?并不是因为要使事情更加通用,而是需要知道传入的是什么类型的 void*
才能进行转换...
有人可以帮助我理解 void*
吗?
在C语言中,使用void *
相当普遍,以创建通用集合。例如,如果您想要一个通用的链表,您可以编写类似以下的代码:
typedef struct node {
void *data;
struct node *next;
} node;
那么你可以创建一个foo
的链表,另一个bar
的链表,以此类推。
然而,在C++中,这种方式很少有用。在典型情况下,您将想要编写等效代码作为模板:
template <typename T>
class node {
T data;
node *next;
};
在旧编译器中,您可以通过结合两种技术来减少生成的代码。在这种情况下,您将使用一组指向 void 的指针来存储数据,然后有一个模板前端只处理将 T * 强制转换为 void * 以存储数据,以及从 void * 到 T * 的强制转换以检索数据。
编译器/链接器的改进使得这种技术(几乎?)完全过时了。旧编译器会为您实例化模板的每个类型生成单独的代码,即使实例化类型是不相关的。当前编译器(或工具链,无论如何 - 相当多的内容都由链接器处理)会识别相同的代码序列,并自动将它们合并在一起。
底线:除非您需要 C 兼容性,或者您正在编写替代 operator new/operator delete 的代码,否则在良好编写的 C++ 中使用 void * 通常是相当罕见的。
uint8_t *
,而不是void *
。在我看来,指向一个8位单元比指向空指针更好。 - Thomas Matthewsvoid*
是一个没有类型的内存地址。当周围代码有其他方式可以知道它所使用的类型时,它非常有用(例如,memchr
需要除了地址以外还要传递内存区域的大小)。
void *
。 - Ed Healdynamic_cast<void *>
。 - Kerrek SBvoid*
在C语言中用于通用编程很有用。请看qsort和bsearch。在C++中,我们有模板,每个方面都比void*
更好,除了一个方面。 - Benjamin Lindley