2011-05-13 45 views
5

鉴于类型转换该A* pA;B* pB;,是否有任何下面类型铸件之间差(查询所有C++风格转换):指针具有和不具有参考

pB = reinterpret_cast<B*>(pA);  // pointer 
pB = reinterpret_cast<B*&>(pA);  // pointer-reference 

回答

5

这两者根本不同,至少在理论上(并且可能在实践中有几个稀有机器)。第一个将指针指向A,并且 将其转换为指向B的指针;从理论上讲,至少,这可能涉及 大小和表示的变化。 (我实际上在机器上工作 ,其中char*大于int*我相当怀疑任何这样的 机器仍然存在,虽然也许在嵌入式世界中......) 秒确实等于*reinterpret_cast<B**>(&pA);它 取pA中的位,并告诉编译器将它们解释为 a B*。如果格式不同,运气不好,如果大小不同,您可能只访问部分pA或访问不属于pA的内存 。

另外,第一个是右值,第二个左值。因此,一些 喜欢:

++ reinterpret_cast<B*>(pA); 

是非法的,但:

++ reinterpret_cast<B*&>(pA); 

不是。这是一种非常有用的技术,用于对代码进行混淆处理,并获取未对齐的指针,指向对象中间的指针或其他不可取消引用的指针。

一般情况下,应避免第二种形式,但有例外情况。Posix保证所有指针,包括指向 函数的指针(但不指向成员的指针— Posix指定一个C ABI, ,它没有指向成员的指针),具有相同的大小和格式,因此第二种形式保证工作。它是你 可以合法地转换返回void*通过dlsym成一个指向 功能的唯一途径:

​​

(在C语言中,你会写:

int (*pf)(int); 
*(void**)(&pf) = dlsym(handle, "functionName"); 

,请参阅 official specification)。这些技巧允许指针类型 之间的转换,这些指针类型在其他方面是不允许的,但取决于标准中的其他保证而不是 。

+0

很好回答Jmaes! – 2011-05-13 21:02:06

1

reinterpret_cast是实现定义。因此理论上,结果可能会有所不同,但在实践中,您可以假设结果是相同的,因为typeid(B*)等于typeid(B*&) =>实际上您在两种情况下投射到相同类型。

0

还有没有的区别。

pB = reinterpret_cast<B*>(pA);  // pointer 

被铸造到该类型的B*一个指针和

pB = reinterpret_cast<B*&>(pA);  // pointer-reference 

撒开到参照的指针。

注意:不存在指向引用的指针。

+2

在他的问题OP已经提到,第一个是指针,第二个是指针的引用。 – 2011-05-13 08:21:57

+0

@Mhhran Hovsepyan:OP说'指针参考',有没有这样的事情?只能引用指针。 – 2011-05-13 08:23:17

+2

英文中的“指针参考”与“参考指针”相同,而不是“参考指针”。 – 2011-05-13 08:26:00

0

功能不同。

如果您使用后一种变体,那么显然存在可维护性差异。你的同事会认为你抽了点东西。 ;-)