当前位置: 首页 > 知识库问答 >
问题:

reinterpret_cast提及shared_ptr

尤俊誉
2023-03-14

让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中都有效。

共有3个答案

胡星汉
2023-03-14

首先,您创建一个对象一个类型为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限定版本对应的有符号或无符号类型的类型,-在其元素或非静态数据成员(包括,递归地,子聚合或包含联合的元素或非静态数据成员),

邵展
2023-03-14

<code>reinterpret_cast</code>通常会导致UB。有时,出于性能原因,你愿意冒险使用它,但你会尽量避免这种事情。在这种情况下,最好使用static_pointer_cast

请注意,即使您不知道,在这种情况下,您可以使用哪种其他类型的转换,并且您愿意冒险使用< code>reinterpret_cast,您也必须在转换前后使用一些验证,否则您将会遇到许多错误,并花费大量时间。

慎建本
2023-03-14

你想要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不会(或者从技术上讲:未定义的行为)

 类似资料:
  • 参考SOC常见问题解答什么时候应该使用static_cast、dynamic_cast和reinterpret_cast? constcast用于移除或向变量添加const,这是唯一可靠、定义明确且合法的移除const的方法。reinterpretcast用于更改类型的解释。 我以合理的方式理解为什么常量变量应该只使用const_cast转换为非常量变量,但我无法找出使用reinterpret_c

  • 这是一个典型的严格混叠违规示例: 但假设我们添加第二: 这段代码正确吗(不调用未定义的行为)? 标准[expr.reinterpret.cast]如下: 注意:将“指针到<code>T1</code>”类型的prvalue转换为“指针到 和<code>T2是对象类型,并且<code>T2的对齐要求不比<code>T 1 我们使用 类型的原始指针值来访问 类型。 当优化打开时,GCC和Clang都会

  • 问题内容: 我需要在python中编写一个正则表达式以从Tweets中提取提及。 我的尝试: 对于@mickey之类的任何提及,它都可以正常工作,但是,在带有@mickey_mouse之类的下划线的提及中,它仅提取@mickey。 如何修改正则表达式以使其在两种情况下均能正常工作? 谢谢 问题答案: 在下一组添加下划线,如下所示: Regex101演示 另外,Twitter Handle规则 允许

  • 阅读https://en.cppreference.com/w/cpp/language/reinterpret_cast我想知道的哪些用例不是UB并且在实践中使用? 上面的描述包含了许多情况,在这些情况下,将指针转换成其他类型是合法的,然后再转换回来也是合法的。但这似乎没什么实际用途。除了通过< code > char * /< code > byte * 指针访问之外,通过< code>rei

  • 禁止点击 未提及的国家 ,这个操作会使在数据集中未提到过的国家在3D地球上不可选。默认设置下此功能不开启。 controller.disableUnmentioned(true); // 禁用此功能 controller.disableUnmentioned(false);