【问题标题】:how to cast void* to shared_ptr<mytype>如何将 void* 转换为 shared_ptr<mytype>
【发布时间】:2023-04-05 09:29:01
【问题描述】:

我有一个 OpenGL 项目的问题,从 void* 指针转换为 shared_ptr&lt;mytype&gt;

我正在使用 Bullet 在刚体上设置指针:

root_physics->rigidBody->setUserPointer(&this->root_directory->handle);

句柄的类型为shared_ptr&lt;mytype&gt;

void* 指针由 Bullet 的库函数 getUserPointer() 返回:

RayCallback.m_collisionObject->getUserPointer()

要转换回mytypestatic_cast 不起作用:

std::shared_ptr<disk_node> u_poi = static_cast< std::shared_ptr<disk_node> >( RayCallback.m_collisionObject->getUserPointer() );

编译时的错误:

/usr/include/c++/4.8/bits/shared_ptr_base.h:739:39: error: invalid conversion from ‘void*’ to ‘mytype*’ [-fpermissive]

知道如何将getUserPointer() 返回的void* 转换为shared_ptr&lt;mytype&gt;

【问题讨论】:

    标签: c++ pointers casting shared-ptr


    【解决方案1】:

    由于您将指针存储到std::shared_ptr 的实例,因此您需要将getUserPointer 返回的值转换为std::shared_ptr&lt;&gt;* 而不仅仅是std::shared_ptr&lt;&gt;

    std::shared_ptr<disk_node>* u_poi
      = static_cast< std::shared_ptr<disk_node>* >(RayCallback.m_collisionObject->getUserPointer());
    

    【讨论】:

    • 虽然这更正了错误,但从 u_poi 访问数据导致另一个错误:错误:‘class std::shared_ptr’没有名为‘name’的成员。为了解决这个问题,我在 static_cast 之前移动了第一个星号。 std::shared_ptr u_poi = * static_cast* >( RayCallback.m_collisionObject->getUserPointer() );
    • 您需要先取消引用指针(指向std::shared_ptr)。 (*u_poi)-&gt;name 应该可以解决问题。
    • 这被认为是常见的做法/安全吗?也就是说,std::shared_ptr 可以安全地存储在库提供的 void* 用户指针中吗?计划使用此解决方案,但想知道此解决方案是否不仅仅是针对此特定问题的答案。
    • @MikeWeir 是的,在您需要与 C 库或考虑不周的 C++ 库交互的情况下,以这种方式使用 void 指针是很常见的。然而,这是不安全的,因为零检查或保证指针是您认为的那样。除非您需要使用 void 指针(即与 C 库的接口),否则您应该避免使用这种方法,而是使用多态基接口。
    • 如果相同的 void* 被强制转换为其他地方的另一个 shared_ptr,底层对象会被删除两次吗?我不明白为什么这种 static_cast 技术可以支持对新生成的共享指针进行适当的核算。
    【解决方案2】:

    我认为有一个更简单的方法:

    1. void* 更改为disk_node*
    2. disk_node* 存储在shared_ptr 中。

    就像这样:

    std::shared_ptr u_poi =
         static_cast(RayCallback.m_collisionObject->getUserPointer());
    

    【讨论】:

      【解决方案3】:

      这就是 reinterpret_cast 的用途:

      reinterpret_cast<std::shared_ptr<disk_node>*>(RayCallback.m_collisionObject->getUserPointer());
      

      【讨论】:

      • reinterpret_cast 在这里是不必要的并且很危险。由于std::shared_ptr&lt;disk_node&gt;* 可以隐式转换为void* static_cast 非常乐意将void* 转换为std::shared_ptr&lt;disk_node&gt;*
      • 此处不恰当地使用了投射。
      猜你喜欢
      • 2012-07-22
      • 1970-01-01
      • 2012-04-12
      • 2014-11-09
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多