C++ 将回调绑定到过期的共享\u ptr?

C++ 将回调绑定到过期的共享\u ptr?,c++,memory-management,callback,shared-ptr,weak-ptr,C++,Memory Management,Callback,Shared Ptr,Weak Ptr,我熟悉std::shared_ptr和std::weak_ptr,知道它们是如何工作的。但是,我希望std::shared_ptr发出一个回调,就像boost信号一样。这将允许及时清理仍然引用已删除对象的std::weak_ptr 是否已经有一些智能指针实现,将报告破坏 解释 我认为std::weak_ptrs中可能存在一个小的设计缺陷,这可能导致错误的内存泄漏。我所说的“错误内存泄漏”是指程序仍然可以访问的对象,但其存在原因不再有效。与真正的内存泄漏不同的是,程序完全不知道真正的内存泄漏,而错

我熟悉
std::shared_ptr
std::weak_ptr
,知道它们是如何工作的。但是,我希望std::shared_ptr发出一个回调,就像boost信号一样。这将允许及时清理仍然引用已删除对象的
std::weak_ptr

是否已经有一些智能指针实现,将报告破坏

解释 我认为
std::weak_ptr
s中可能存在一个小的设计缺陷,这可能导致错误的内存泄漏。我所说的“错误内存泄漏”是指程序仍然可以访问的对象,但其存在原因不再有效。与真正的内存泄漏不同的是,程序完全不知道真正的内存泄漏,而错误的内存泄漏只是未正确清理的一部分

另一个描述可以在

使用观察者

  • 释放对象的问题之一是,在其他对象仍指向对象时,您可能已经这样做了。这将引入悬空指针和崩溃!为了对抗指针悬空的邪恶,我喜欢使用一个基本的“观察者”系统。这与上面讨论的弱参考没有什么不同。实现如下:

  • 创建一个基类“Watchable”,该基类派生自删除对象时应该广播的对象。可观察对象跟踪指向它的其他对象。 创建一个“观察者”智能指针,当指定给该指针时,该指针会将自身添加到对象列表中,以便在其目标离开时得到通知

  • 这项基本技术将大大有助于解决悬而未决的指针问题,而不会牺牲对何时销毁对象的显式控制

    例子 假设我们使用boost实现了observer模式。我们有一个类
    可观察的
    ,它包含一个或多个信号,还有一个类
    可观察的
    ,它连接到
    可观察的
    的信号

    当删除观察者时,
    可观察者的插槽会发生什么情况?当我们什么都不做时,连接就不会指向任何地方,当发出信号时,我们可能会收到一个分段错误

    为了解决这个问题,boost的插槽还提供了一种方法
    跟踪(const-weak\u-ptr&tracked\u-object)
    。这意味着,如果我调用
    跟踪
    并将
    弱ptr
    传递给
    观察者
    ,则当
    弱ptr
    过期时将不会调用插槽。相反,它将从信号中删除

    问题在哪里?让我们删除一个
    观察者
    ,再也不要调用
    可观察的某个信号
    。在这种情况下,跟踪的连接也将永远不会被删除。下次我们发射信号时,它将被清除。但我们不排放它。因此,连接只是停留在那里,浪费资源

    一个解决方案是:当拥有
    共享时,ptr
    应该在销毁其对象时发出信号。这将允许其他对象及时清理。所有对已删除对象具有
    弱\u ptr
    的对象都可能注册回调,并且可以避免错误的内存泄漏

    这将允许仍然引用已删除对象的std::weak_ptr, 要及时清理

    实际上,它们只保存弱引用,这并不能防止对象被破坏。按住对象的
    弱\u ptr
    s并不能阻止以任何方式对其进行销毁或删除

    你给我的这句话听起来像是那个家伙不知道哪些对象拥有哪些其他对象,而不是有一个适当的所有权层次结构,其中明确定义了每件事物的寿命

    至于boost::signals2,这就是a的用途——也就是说,你做错了

    长话短说,标准中的工具没有任何问题(除了
    auto_ptr
    ,它坏了,我们现在有了
    unique_ptr
    )。问题是您没有正确使用它们。

    //
    
    //
    // create a C function that does some cleanup or reuse of the object
    //
    void RecycleFunction
    (
       MyClass * pObj
    )
    {
       // do some cleanup with pObj
    }
    
    //
    // when you create your object and assign it to a shared pointer register a cleanup function
    //    
    
        std::shared_ptr<MyClass> myObj = std::shared_ptr<MyClass>(  new MyClass,  
                                                                    RecycleFunction);
    
    //创建一个C函数,对对象进行清理或重用 // 无效循环函数 ( MyClass*pObj ) { //用pObj做一些清理 } // //创建对象并将其指定给共享指针时,请注册一个清理函数 // std::shared_ptr myObj=std::shared_ptr(新MyClass, 循环功能);

    最后一次引用过期后,将使用对象作为参数调用“RecyleFunction”。我使用此模式回收对象并将其插入池中。

    作用域\u连接没有帮助。。。他们只是转移了问题。作用域_连接必须存储在观察器中的container中。如果删除了可观察对象,会发生什么?观测者的scoped_连接不会知道这一点,而且容器中有垃圾。我同意你的观点,std指针很好而且很有用。但是,有时必须使用弱ptr来保留指向对象的指针,该对象可能会被删除。。没有推迟删除。假设我在线程池上发布了一个繁重的计算,结果应该调用对象上的一个方法,该方法可能会被销毁。。。这也是使用弱ptr的时候。但是,如果对象已经被删除,那么繁重的计算可能会选择知道,它不需要完成。@JackSabbath:不,您会将它们存储在observative中。当可观察对象被破坏时,作用域连接也被破坏,然后再见连接。另外,以这种方式使用
    弱\u ptr
    是完全正确的,因为它不会阻止对象以任何方式被删除。然而,这种设计涉及太多关于生命周期的运行时推测,与实际设计相差甚远。存储在Observable中的任何连接都不会被删除