带有和没有引用的指针类型转换

时间:2011-05-13 08:04:01

标签: c++ casting

鉴于A* pA;B* pB;,下面的类型转换(查询所有C ++样式转换)之间存在 ANY 差异:

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

4 个答案:

答案 0 :(得分:5)

两者完全不同,至少在理论上是这样(并且可能是开启的 一些罕见的机器,在实践中)。第一个采用指向A的指针,和 将其转换为指向B的指针;理论上,至少,这可能涉及 规模和代表性的变化。 (我实际上在机器上工作过 其中char*大于int*。我很怀疑任何这样的 机器仍然存在,虽然可能在嵌入式世界......) 第二个实际上相当于*reinterpret_cast<B**>(&pA);它 获取pA中的位,并告诉编译器将它们解释为 一个B*。如果格式不同,运气不好,如果尺寸不同 不同的是,您可能只访问pA的一部分或访问内存 这不属于pA

另外,第一个是右值,第二个是左值。因此,有些东西 像:

++ reinterpret_cast<B*>( pA );

是非法的,但是:

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

是没有的。这是混淆代码和获取代码的有用技术 未对齐的指针,指向对象中间的指针或其他 你不敢去引用的指针。

一般来说,应避免使用第二种形式,但很少见 例外。 Posix保证所有指针,包括指针 函数(但不是指向成员的指针-Posix指定C ABI, 它没有指向成员的指针),具有相同的大小和格式, 所以第二种形式保证有效。这是你唯一的方式 可以合法地将void*返回的dlsym转换为指针 功能:

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

(在C中,你会写:

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

,见 official specification。)这些技巧允许指针类型之间的转换 这是不允许的,但不取决于额外的保证 在标准中。

答案 1 :(得分:1)

reinterpret_cast是实现定义的。所以理论上结果可能不同,但实际上你可以假设结果是相同的,因为typeid(B*)等于typeid(B*&) =&gt;实际上你在两种情况下都是同一类型。

答案 2 :(得分:0)

存在差异。

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

正在转换为B*

类型的指针
pB = reinterpret_cast<B*&>(pA);     // pointer-reference

正在转换为引用指针。

注意:没有指向引用的指针。

答案 3 :(得分:0)

没有功能性差异。

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