转换为void *并返回Original_Data_Type *

时间:2012-09-05 06:01:07

标签: c++ casting void-pointers

我已经看过很多次使用C ++,特别是在各种线程实现中。我想知道这是否有任何陷阱/问题?有什么方法可以在我们转换为void *并再次返回时遇到错误或未定义的条件?如果有的话,我们该如何解决这些问题?

谢谢。

4 个答案:

答案 0 :(得分:3)

我已经没有看到C ++中的版本无效。 C语言中的一种习惯在C ++中被主动避免。

施放到void *会删除所有类型的安全性。

如果您使用reinterpret_caststatic_cast从指针类型转换为void*并返回相同的指针类型,您实际上可以通过标准保证结果将是明确的

危险在于你可能会将void*强加给错误的类型,因为你不再确定正确的类型是什么。

答案 1 :(得分:2)

  

我想知道这是否有任何陷阱/问题?

在将void*转换回特定类型时,您需要绝对确定,如果不这样做,最终会出现未定义行为和潜在灾难。使用void *后,您将失去 类型安全 。很难跟踪void *实际指向的类型,没有保证或确定它确实指向你将其类型转换回来的类型的方法。

  

当我们转换为void *并再次返回时,有没有办法让我们遇到错误或未定义的条件?

是的,#1中提到的情景。

  

如果有任何问题我们应该如何解决?

完全避免在C ++中使用void *,而是使用模板和继承 在C语言中,你可能在某些情况下绝对需要它,但尽量将其使用保持在最低限度 底线,
C / C ++允许你徒步射击,这取决于你做或不做。

答案 2 :(得分:1)

我知道驱动程序中的很多函数等使用void指针将数据返回给调用者,模式大致相同:

int requestSomeData(int kindOfData, void * buffer, int bufferSize);

此函数可以将不同的数据类型作为参数。 他们所做的是使用bufferSize作为参数来避免写入他们不应该写入的内存位置。 如果bufferSize不匹配或小于应返回的数据,则该函数将返回错误代码。

无论如何:在编写任何代码之前,请避免使用它们或思考三倍。

答案 3 :(得分:1)

标准授予的唯一内容是,A* pa(A*)(void*)pA == pA。 结果

void* pv = pA;
A* pA2 = (A*)pv;
pA2->anything ...

pA->anything ...

相同

其他所有内容都“未定义”,ad -in事实上是以某种方式依赖于实现。

根据我的经验,这里有一些已知的陷阱:

  • A派生形式BpApB视为A*B*pB=pA使pB指向A的基础。这并不意味着pBpA是相同的地址。因此pB = (B*)(void*)pA实际上可以将其他任何地方指向A(虽然单个继承对象通常实现共享相同的原点,所以它显然工作正常)
  • 反之亦然:假设pB实际指向ApA = (A*)(void*)pB并不一定正确指向A对象。正确的方法是pA = static_cast<A*>(pB);
  • 如果以上几点可以与大多数单继承实现一起使用,那么除了第一个以外的基数将永远不会使用多个继承:如果class A: public Z, public B { ... };不为空,请考虑Z给定{{ 1}},A子组件将不具有相同的A地址。 (并且C ++中的多重继承在任何地方都是iostream)
  • 有时事情也取决于平台:B(其中(char*)(void*)pI指向一个整数)与“pI如果*pI(-128)不同.. + 127)“(它只会在小端机器上)

一般来说,不要假设类型之间的转换只是改变解释地址的方式