找到你要的答案

Q:Binding a callbacks to an expiring shared_ptr?

Q:绑定一个回调即将到期的shared_ptr?

I am familiar with std::shared_ptr and std::weak_ptr and know how they work. However, I would like the std::shared_ptr to emit a callback, like a boost signal. This would allow std::weak_ptr, who still refer to the deleted object, to be cleaned up right in time.

Is there maybe already some smart pointer implementation, which will report the destruction?

Explanation

I think there might be a small design flaw in std::weak_ptrs, that can lead to false memory leaks. By "false memory leak" I mean an object, that is still accessible by the program, but whose reason of existence is not valid anymore. The difference to a true memory leak is, that the true memory leak is completely unknown by the program, while the false leak is just a part that wasn't cleaned up properly.

Another description can be found at codingwisdom.com

Use Watchers

  1. One of the problems with freeing an object is that you may have done so while other things are still pointing at it. This introduces dangling pointers and crashes! To combat the evil of dangling pointers, I like to use a basic "watcher" system. This is not unlike the weak reference discussed above. The implementation is like this:

  2. Create a base class "Watchable" that you derive from on objects that should broadcast when they're being deleted. The Watchable object keeps track of other objects pointing at it. Create a "Watcher" smart pointer that, when assigned to, adds itself to the list of objects to be informed when its target goes away.

This basic technique will go a long way toward solving dangling pointer issues without sacrificing explicit control over when an object is to be destroyed.

Example

Let's say we implement the observer pattern using boost Boost Signals2. We have a class Observable, that contains one or more signals and another class Observer, that connects to Observable's signals.

What would happen to Observable's slots, when a observing Observer is deleted? When we do nothing, then the connection would point to nowhere and we would probably receive a segmentation fault, when emitting the signal.

To deal with this issue, boost's slots also offer a method track(const weak_ptr<void>& tracked_object). That means, if I call track and pass a weak_ptr to Observer, then the slot won't be called when the weak_ptr expired. Instead, it will be deleted from the signal.

Where is the problem? Let's we delete an Observer and never call a certain signal of Observable ever again. In this case, the tracked connection will also never be deleted. Next time we emit the signal it will be cleaned up. But we don't emit it. So the connection just stays there and wastes resources.

A solution would be: when owning shared_ptr should emit a signal when it is destroying it's object. This would allow other other objects to clean up right in time. Everything that has a weak_ptr to the deleted object might register a callback and false memory leaks could be avoided.

我熟悉std::shared_ptr和std::weak_ptr,知道他们是如何工作的。但是,我会像std::shared_ptr发出回调,就像一个升压信号。这将允许std::weak_ptr,谁还将删除的对象,被清理的正是时候。

是否已经有一些智能指针实现,将报告销毁?

Explanation

我觉得可能是性病的一个小的设计缺陷::weak_ptrs,可能导致错误的内存泄漏。由“假内存泄漏”,我的意思是一个对象,仍然是由程序访问,但其存在的原因是无效的。一个真正的内存泄漏的区别是,真正的内存泄漏是完全未知的程序,而假泄漏只是一部分,没有清理正确。

另一种描述可以发现在codingwisdom.com

使用观察者

  1. 释放对象的问题之一是,你可能已经这样做,而其他的东西仍然指向它。这将引入挂起指针和崩溃!打击悬垂指针邪恶,我喜欢用一个基本的“守望者”系统。这与上面所讨论的弱引用不同。执行是这样的:

  2. Create a base class "Watchable" that you derive from on objects that should broadcast when they're being deleted. The Watchable object keeps track of other objects pointing at it. Create a "Watcher" smart pointer that, when assigned to, adds itself to the list of objects to be informed when its target goes away.

这一基本技术将有助于解决悬垂指针问题,而不牺牲显式控制对象何时被销毁。

Example

我们使用Boost升压Signals2观察者模式。我们有一个可观测的类,它包含一个或多个信号和另一个类观察者,它连接到观察到的信号。

当观察者被删除时,观察者的槽会发生什么?当我们什么都不做,那么连接将指向任何地方,我们可能会收到分割故障时,发射信号。

为了解决这个问题,增加的插槽,还提供了一个跟踪方法(const weak_ptr <;无效>;&;tracked_object)。这意味着,如果我叫轨道,通过weak_ptr观测器,然后槽不能当weak_ptr过期。相反,它将从信号中删除。

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

一个解决办法是:当拥有shared_ptr应该发出一个信号时,它是破坏它的对象。这将允许其他对象及时清理干净。一切有weak_ptr到删除的对象可能登记回调和假内存泄漏是可以避免的。

answer1: 回答1:

This would allow std::weak_ptr, who still refer to the deleted object, to be cleaned up right in time.

Actually, they only hold weak references, which do not prevent the object from being destroyed. Holding weak_ptrs to an object does not prevent it's destruction or deletion in any fashion.

The quote you've given sounds to me like that guy just doesn't know which objects own which other objects, instead of having a proper ownership hierarchy where it's clearly defined how long everything lives.

As for boost::signals2, that's what a scoped_connection is for- i.e., you're doing it wrong.

The long and short is that there's nothing wrong with the tools in the Standard (except auto_ptr which is broken and bad and we have unique_ptr now). The problem is that you're not using them properly.

This would allow std::weak_ptr, who still refer to the deleted object, to be cleaned up right in time.

实际上,它们只持有弱引用,不妨碍对象被破坏。控股weak_ptrs对象并不妨碍它以任何方式破坏或缺失。

你给我的引语听起来像那个家伙只是不知道哪一个对象拥有其他对象,而不是有一个适当的所有权层次,它清楚地定义了多久的一切生活。

为提高::Signals2,那即scoped_connection是什么,你做的不对。

总之,在标准没有错的工具(除了auto_ptr是破坏和我们有unique_ptr现在)。问题是你没有正确使用它们。

answer2: 回答2:
//
// 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);

Once the last reference expires "RecyleFunction" is called with your object as parameter. I use this pattern to recycle objects and insert them back into a pool.

//
// 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);

一旦最后参考到期”recylefunction”叫你的对象作为参数。我使用这个模式来回收对象并将它们插入池中。

c++  memory-management  callback  shared-ptr  weak-ptr