我已经看过很多次使用C ++,特别是在各种线程实现中。我想知道这是否有任何陷阱/问题?有什么方法可以在我们转换为void *并再次返回时遇到错误或未定义的条件?如果有的话,我们该如何解决这些问题?
谢谢。
答案 0 :(得分:3)
我已经没有看到C ++中的版本无效。 C语言中的一种习惯在C ++中被主动避免。
施放到void *会删除所有类型的安全性。
如果您使用reinterpret_cast
或static_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
派生形式B
,pA
和pB
视为A*
和B*
。 pB=pA
使pB
指向A
的基础。这并不意味着pB
和pA
是相同的地址。因此pB = (B*)(void*)pA
实际上可以将其他任何地方指向A(虽然单个继承对象通常实现共享相同的原点,所以它显然工作正常)pB
实际指向A
,pA = (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)“(它只会在小端机器上)一般来说,不要假设类型之间的转换只是改变解释地址的方式。