【问题标题】:Dereferencing the void pointer in C++在 C++ 中取消引用 void 指针
【发布时间】:2012-05-23 19:23:20
【问题描述】:

我正在尝试实现一个通用链表。节点的结构如下 -

typedef struct node{
        void *data;
        node *next;      
};

现在,当我尝试为数据分配地址时,例如假设为 int,例如 -

int n1=6;
node *temp;
temp = (node*)malloc(sizeof(node));
temp->data=&n1;

如何从节点获取 n1 的值?如果我说-

cout<<(*(temp->data));

我明白了-

`void*' is not a pointer-to-object type 

当我为它分配一个 int 地址时,void 指针不会被强制转换为 int 指针类型吗?

【问题讨论】:

  • 为什么在 C++ 程序中使用 malloc 和 C 风格的指针?
  • 如果这不是练习,请停止重新发明轮子并使用例如glib中提供的链表
  • @PaulRL OP 在他的问题标题中提到 C 作为实现语言。
  • 我们可以请不要在这里问 cout/printf 吗?这只是关于取消引用 void 指针,是的,它是一个练习。
  • @DavidHeffernan:是的。这就是当时应该指出的。在 C++ 中使用 malloc 就可以了。这种在 C++ 中看不起mallocfree 的趋势已经成为一种我不同意的风格声明。

标签: c++ c pointers linked-list


【解决方案1】:

您必须首先将void* 类型转换为实际有效的指针类型(例如int*),以告诉编译器您希望取消引用多少内存。

【讨论】:

  • 因此,在这种通用链表的情况下,每个节点都有不同类型的数据,例如 int 或 char 或 char*。那么,要获得我需要进行类型转换的每个数据的值?这意味着我不能遍历链表并以通用方式获取数据值?
  • 您需要进行类型转换(知道底层类型)或创建一个知道底层类型并可以正确返回其值的通用容器。
  • @theharshest,对于通用链表,您应该使用模板化结构,例如std::list
  • 如果同一个列表的节点不共享一个共同的类型,你可能不得不将它们“装箱”(让它们的值由派生自基类的特殊类保存)。
【解决方案2】:

无法取消引用 void 指针。您需要将其转换为合适的非空指针类型。在这种情况下,int*

cout << *static_cast<int*>(temp->data);

由于这是 C++,您应该使用 C++ 类型转换而不是 C 样式类型转换。而且你不应该在 C++ 等中使用malloc

【讨论】:

  • ...如果您正在编写“通用”链接列表,则应该使用泛型。或者我们称之为模板。 :-)
  • 我想知道为什么这个答案和接受的答案都被否决了。
  • 我认为这可能是因为即使您完全正确地回答了问题,但使用该答案仍然会得到该死的糟糕代码! :-)
  • @user 这可以解释对其他答案的支持。在我看来,对解决问题的答案投反对票是很奇怪的。
  • 我可以想象“应该使用 C++ 转换而不是 C 风格”的一两个反对票。看到它最终如何无关紧要,与问题的关系更小。只是猜测。
【解决方案3】:

无法取消引用 void 指针。您需要将其转换为合适的非空指针类型。问题是关于 C++,所以我建议考虑使用模板来实现你的目标:

template <typename T> struct node
{
   T *data;
   node<T> *next;      
};

然后:

int n1=6;
node<int> *temp = new node<int>();
temp->data=&n1;

最后:

cout << (*(temp->data));

可以进行类型转换,但这将是 C 风格的类型不安全解决方案,而不是 C++ 解决方案。

【讨论】:

  • typedef 在 C++ 中是不必要的,而且由于我们正在使用模板......而且,将数据设置为 T* 似乎相当无用,一个简单的 T 就足够了。跨度>
  • 已修复。 T* 由原作者提供。
  • 另外,请改用std::unique_ptr&lt;node&lt;T&gt;&gt; next;(或者最好使用boost::optional&lt;node&lt;T&gt;&gt; next;)。并且第一个节点不需要动态分配;只需使用node&lt;int&gt; temp;
  • @SergeyK.:我不同意。 OP 不使用T*,他使用void*。重要的区别是多态性需要间接性(大小问题),但是使用参数代码不再需要任何多态性。因此T 是一个可行的替代品。
  • 如果是 T,您必须存储一个副本(值),如果是 T*,则可以共享该值。不过,这对于整数类型并不重要。
【解决方案4】:

将 temp-> 数据类型转换为 int 然后打印。

cout<<*((int *)temp->data);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多