【问题标题】:when to use void* in c++何时在 C++ 中使用 void*
【发布时间】:2023-03-31 12:40:01
【问题描述】:

我正在尝试对void* 以及它的适当用途以及我应该知道的任何潜在滥用用途进行总结。 (意思很酷,没有错)。

我不明白如何以及为什么要使用void*。如果我理解,我需要将当前指针转换为void*,然后在我想使用它时转换回原始指针......?

为什么这是有益的?不要让事情变得通用,因为我需要知道传递了什么类型的 void* 来进行演员表...

谁能帮我理解void*

【问题讨论】:

  • 在 C++ 中永远不要在非常特殊情况下使用void *expect。
  • 这是那些功能之一。如果你不知道你是否需要它,你就不需要它。
  • 如果你有一个指向多态类型对象的指针,并且想要找出包含它的最派生对象的地址,请在其上使用dynamic_cast<void *>
  • void * 类型的变量用于寻址原始内存,因此它们是operator newoperator delete 的标准通信类型。
  • 啊,我记得是这样的:stackoverflow.com/questions/16866333/…

标签: c++ pointers syntax


【解决方案1】:

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 * 通常很少见。

【讨论】:

  • 对于最小可寻址单元为 8 位的平台,我建议使用 uint8_t * 而不是 void *。在我看来,指向一个 8 位单元总比没有指针好。
【解决方案2】:

void* 是一个没有类型的内存地址。当它周围的代码有其他方式知道它正在使用什么类型时(例如,memchr 除了地址之外还需要传递内存区域的大小)时,它很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 2012-11-02
    相关资源
    最近更新 更多