在你的建议中
然后客户端将负责递减计数器。
表示有问题的客户负责内存管理,并且您信任她。我还是不明白为什么。
实际上无法修改 shared_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
这样,您的客户端“递减”计数器实际上是您的客户端使用您使用的 id 调用回调方法,并且您删除了一个 shared_ptr :)
黑客 boost::shared_ptr
正如我所说的(因为我们在 C++ 中)实际上侵入 shared_ptr 是可能的。甚至有几种方法可以做到这一点。
最好的方法(也是最简单的)就是将文件复制到另一个名称下(my_shared_ptr ?),然后:
- 更改包含防护
- 在开头包含真正的 shared_ptr
- 用您自己的名称重命名 shared_ptr 的任何实例(并将私有更改为公共以访问属性)
- 删除所有已在真实文件中定义的内容以避免冲突
通过这种方式,您可以轻松获得自己的 shared_ptr,您可以访问它的计数。但是它并没有解决让 C 代码直接访问计数器的问题,您可能必须在这里“简化”代码以将其替换为内置的(如果您不是多线程的,则该代码可以工作,并且是彻头彻尾的灾难性如果你是)。
我故意省略了“reinterpret_cast”技巧和指针偏移。有很多方法可以非法访问 C/C++ 中的某些内容!
我可以建议你不要使用这些黑客吗?我上面介绍的两种解决方案应该足以解决您的问题。