手动递增和递减boost :: shared_ptr?

dzh*_*lil 5 c++ boost shared-ptr

有没有办法在C++中手动递增和递减shared_ptr的计数?

我试图解决的问题如下.我正在用C++编写一个库,但接口必须是纯C.在内部,我想使用shared_ptr来简化内存管理,同时保留通过C接口传递原始指针的能力.

当我通过接口传递一个原始指针时,我想增加引用计数.然后,客户端将负责调用一个函数,该函数将在不再需要传递的对象时减少引用计数.

jde*_*aan 10

也许你正在使用boost :: shared_ptr跨越DLL边界,什么将无法正常工作.在这种情况下,boost :: intrusive_ptr可能会帮助你.这是滥用shared_ptr人员的常见情况,试图用脏兮兮的工作来解决......也许我的错在你的情况下但是应该没有充分的理由去做你想做的事情;-)

ADDED 07/2010:问题似乎来自DLL加载/卸载,而不是来自shared_ptr本身.甚至提升理由也没有说明boost::intrusive_ptr应该优先考虑的案例shared_ptr.我转而使用.NET开发并没有按照TR1关于这个主题的细节,所以要注意这个答案现在可能不再有效......


Mat*_* M. 7

在你的建议中

然后,客户将负责减少计数器.

意味着有问题的客户负责内存管理,并且您信任她.我还是不明白为什么.

实际上不可能修改sh​​ared_ptr计数器......(哼,我最后会解释如何...)但还有其他解决方案.

解决方案1:完成对客户的所有权

移交指向客户端的指针(shared_ptr :: release)并期望它在回调时将所有权传递给您(或者只是在没有真正共享的情况下删除对象).

这实际上是处理原始指针时的传统方法,它也适用于此处.缺点是您实际上只释放了此shared_ptr的所有权.如果对象实际上是共享的,那可能会给你带来不便......所以请耐心等待.

解决方案2:使用回调

此解决方案意味着您始终保持所有权并负责在客户端需要时保持此对象的活动(并且踢).当客户端完成对象时,您希望她告诉您并在您的代码中调用一个将执行必要清理的回调.

struct Object;

class Pool // may be a singleton, may be synchronized for multi-thread usage
{
public:
  int accept(boost::shared_ptr<Object>); // adds ptr to the map, returns NEW id
  void release(int id) { m_objects.erase(id); }

private:
  std::map< int, boost::shared_ptr<Object> > m_objects;
}; // class Pool
Run Code Online (Sandbox Code Playgroud)

这样,你的客户端'递减'计数器实际上是你的客户端使用你使用的id调用回调方法,你删除一个shared_ptr :)

黑客提升:: shared_ptr

正如我所说的那样(因为我们使用的是C++)可以实际入侵shared_ptr.甚至有几种方法可以做到这一点.

最佳方式(和最简单的)只是将文件复制下来以其它名称,然后(my_shared_ptr?):

  • 改变包括警卫
  • 在开头包含真正的shared_ptr
  • 使用您自己的名称重命名shared_ptr的任何实例(并将private更改为public以访问属性)
  • 删除已在真实文件中定义的所有内容以避免冲突

这样您就可以轻松获得自己的shared_ptr,您可以访问该计数.它没有解决让C代码直接访问计数器的问题,你可能必须在这里"简化"代码以通过内置替换它(如果你不是多线程的话,这是有效的,并且是彻头彻尾的灾难性的如果你是).

我故意省略了'reinterpret_cast'技巧,指针偏移了一些.有很多方法可以非法访问C/C++中的某些东西!

我可以建议你不要使用黑客吗?我上面介绍的两个解决方案应该足以解决您的问题.