【问题标题】:boost shared_ptr casting to void*将 shared_ptr 强制转换为 void*
【发布时间】:2012-04-12 16:49:55
【问题描述】:

我正在使用 libev,它需要将我的数据转换为 void* 以符合其预定义的结构。我需要将 boost::shared_ptr 转换为 void*,然后将 void* 转换回 boost::shared_ptr。这是我的代码

void foo(boost::shared_ptr<string>& a_string)
{
 void* data = (void*)a_string.get();
 boost::shared_ptr<string> myString((string*)data);
}

我很确定这可以正常工作,但是我的代码设置方式我相信所有对我的字符串的 shared_ptr 引用都超出了范围,因为这种转换方法不会增加 use_count,因此 shared_ptr 正在释放内存,而我还是需要的。

有没有办法手动增加/减少 use_count?理想情况下,当我转换为 void* 时,我会增加 use_count,将我的 void* 传递给另一个函数,将 void* 转换回 shared_ptr 并减少 use_count。

或者如果有人知道这个问题的另一种解决方案,我可以使用任何帮助。

【问题讨论】:

  • 您可以将观察者存储在一个包含观察者和shared_ptr 的类中。这将确保观察者的生命周期与shared_ptr 拥有的对象的生命周期相匹配或超过。另外,为什么不存储shared_ptr本身的地址而不是存储指向对象的地址呢?
  • 我通过创建一个包含 shared_ptr 的结构并将该结构转换为 void* 找到了一个技巧。不确定我对这个解决方案的感觉如何。另外,我在某个论坛上看到你不应该使用 shared_ptr 的地址。
  • @user1229962:你将void* 传递给什么?
  • void* 在事件回调中被传递回 SharedPointer。到那时,原始的 SharedPointers 都超出了范围。我想我只需要在堆上分配一个 shared_ptr 并将其传递给 void,然后在回调中删除它。

标签: c++ boost shared-ptr


【解决方案1】:

执行此操作的唯一真正方法是将shared_ptr 分配到可以存活足够长的位置,然后将void* 设置为指向该位置。

【讨论】:

    【解决方案2】:

    如果将void* 转换回boost::shared_ptr,它将是一个新的共享指针,不会链接到任何其他也指向`void* 变量指向的内存的共享指针。

    我认为您需要做的是将enabled_shared_from_this 支持添加到您正在考虑使用带有该代码的 shared_ptrs 的类中。

    这允许您获得一个 shared_ptr,它将通过您类上的成员函数 (shared_from_this) 与现有 shared_ptrs 共享所有权。

    有关详细信息,请参阅boost enabled_shared_from_this docs

    【讨论】:

      【解决方案3】:

      试试weak_ptr

      shared_ptr<int> p(new int(5));
      weak_ptr<int> q(p);
      

      编辑:抱歉,我没有正确阅读问题;您可以尝试将其保持在范围内,以免被清理

      更新:如果在调用后引用变量,弱指针实际上可能会起作用,因为编译器无法优化 a_string shared_ptr 的破坏(因此防止 decr refcount 为零 -> 释放) 在你使用底层指针之前

      所以你可以这样做:

      void foo(boost::shared_ptr<string>& a_string)
      {
       void* data = (void*)a_string.get();
       boost::shared_ptr<string> myString((string*)data);
       weak_ptr<string> temp(a_string); // prevent destruction before above line
       // or reference a_string in any meaningless way that CANT be optimised out 
       // pre-emptively by the compiler
      }
      

      a_string 可能仍需要在 foo 之外的某个地方引用,具体取决于上下文以及您对 void 指针所做的事情(以及它是否创建新副本或对 void 数据进行操作)

      【讨论】:

      • aweak_ptr 不会增加 use_count,因此仍会释放内存。 weak_ptr 有什么帮助?
      猜你喜欢
      • 2012-07-22
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多