让B从a类派生。通过阅读各种帖子,我有一个印象,铸造像在
const std::shared_ptr<const A> a(new B());
const std::shared_ptr<const B>& b = reinterpret_cast<const std::shared_ptr<const B>&>(a);
出于某种原因,不鼓励使用reinterpret_pointer_cast。但是,出于性能原因,我希望避免创建新的shared_ptr。上述代码合法吗?这会导致不明确的行为吗?它似乎在gcc和VisualStudio中都有效。
你想要static_pointer_cast。
const std::shared_ptr<const A> a(new B());
const std::shared_ptr<const B> b = std::static_pointer_cast<const B>(a);
我非常怀疑上述内容会导致任何性能问题。但是,如果有证据表明shared_ptr会产生性能问题,那么就退回到原始指针:
const B* pB = static_cast<const B*>(a.get());
另一个提示。请尽量避免在具有继承关系的类之间reinterpret_cast
。在存在虚拟方法和/或多重继承的情况下,static_cast
将正确地将指针偏移量调整为正确的 vtable 或基本偏移量。但reinterpret_cast
不会(或者从技术上讲:未定义的行为)
<code>reinterpret_cast</code>通常会导致UB。有时,出于性能原因,你愿意冒险使用它,但你会尽量避免这种事情。在这种情况下,最好使用static_pointer_cast
。
请注意,即使您不知道,在这种情况下,您可以使用哪种其他类型的转换,并且您愿意冒险使用< code>reinterpret_cast,您也必须在转换前后使用一些验证,否则您将会遇到许多错误,并花费大量时间。
首先,您创建一个对象一个
类型为constd::shared_ptr
如果可以使用reinterpret_cast将类型为“指向 T2 的指针”的表达式显式转换为类型“指向 T2”,则 T1 类型的 gl 值表达式可以转换为类型“对 T2 的引用”,但使用指定的类型。[ 注意:也就是说,对于左值,引用强制转换reinterpret_cast(x) 与转换 *reinterpret_cast(
对于指针,reinterpret_cast可以归结为转换为void*
,然后转换为目标类型:
72当对象指针类型的prvalue v转换为对象指针类型"指针到cv T"时,结果是static_cast
两个静态类型转换的语义定义如下:
类型为“指向cv1 void的指针”的prvalue可以转换为类型为“指向cv2 T的指针”的prvalue,其中T是一个对象类型,cv2与cv1具有相同的cv资格,或者比cv1具有更高的cv资格。空指针值被转换为目标类型的空指针值。如果原始指针值表示内存中一个字节的地址A,并且A满足T的对齐要求,则结果指针值表示与原始指针值相同的地址,即A。任何其他此类指针转换的结果都是未指定的。
我正在使用的平台有16位或32位的近指针和远指针。在这种情况下,类型<code>shared_ptr
然而,关于reinterpret_cast引用的第一个子句也包含一个注释
[ Note: That is, for lvalues, a reference
cast reinterpret_cast<T&>(x) has the same effect as the conversion *reinterpret_cast<T*>(&x) with
the built-in & and * operators (and similarly for reinterpret_cast<T&&>(x)). —end note ]
因此,基本上,强制转换在语义上与具有即时取消引用的指针转换相同。即使指针具有相同的大小(且对齐方式兼容),使用强制转换的指针也会违反严格的别名规则,因为取消引用是一种访问。
如果程序试图通过除以下类型之一之外的glvalue访问对象的存储值,则行为未定义: 53-对象的动态类型,-对象动态类型的cv限定版本,-与对象动态类型相似的类型(如4.4中定义的),-与对象动态类型对应的有符号或无符号类型的类型,-与对象动态类型的cv限定版本对应的有符号或无符号类型的类型,-在其元素或非静态数据成员(包括,递归地,子聚合或包含联合的元素或非静态数据成员),