- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有使用 std::function 模板实现回调的类。我最近注意到,我销毁了回调中的对象(即 std::function 销毁了自身)。
这是一个众所周知的问题吗? std::function 设计者是否预见到它可能发生(std::function 是否对这种情况具有弹性)?
示例代码:
struct Sample
{
std::function<void()> callback;
void emit_callback ()
{
callback ();
}
}
void callback(Sample* object)
{
delete object;
}
/////////////////////////////////////////////
Sample* object = new Sample();
object->callback = std::bind(&callback, object);
object->emit_callback ();
最佳答案
在严重依赖信号和槽类型的事件/通知设计的非常复杂的系统中,这可能会成为一个相当大的设计问题。
如果您将一个对象绑定(bind)函数/方法连接到一个信号并且该对象被销毁,则没有任何固有的内置方法来防止信号被第二次调用并通过悬挂对象访问被销毁的对象如果您在对象被销毁时忘记断开插槽的连接,则指针。
缓解此问题的一种方法是将 shared_ptr 绑定(bind)到对象而不是指针。但是,这可以将悬空指针换成逻辑资源泄漏,这不仅会泄漏内存,还会通过阻止对象在应销毁时被销毁来触发不可预知的行为。它还要求您将所有此类对象放在堆上。
将弱引用绑定(bind)到对象可以解决此问题而不会出现这些问题,但仍然会在信号中留下大量被破坏的插槽,除非您找到合适的时间清理所有已被破坏的插槽。它还会在每次调用回调时强制执行运行时检查,以查看弱引用是否指向一个已经被销毁的对象,这可能会成为一个不小的开销,特别是因为弱引用有效性检查通常涉及将其转换为强引用并为线程安全做一些原子 CAS 类型的操作。您还必须将所有此类对象放在堆上。
另一种缓解这种情况的方法是让您的信号设计返回一个强引用(shared_ptr
或有时 unique_ptr
很好,例如)到一种代理对象,当销毁时,它会自动断开插槽与信号的连接。然后,连接到该信号的客户端可以捕获这些对象并将其以与其生命周期相关的方式存储在某个地方。
不幸的是,您确实需要卷起袖子为这些案例选择更高级别的设计。 std::function
之类的东西本身并不能防止这些安全问题。
另一个让您体验痛苦的令人头疼的东西是在一个非常动态的系统中,它允许在不重新启动的情况下动态加载甚至卸载插件。在那些情况下,std::function
之类的东西可能不仅会绑定(bind)到指向已经以连 shared_ptr/weak_ptr
也无法保护的方式被破坏的资源你,但它指向的函数甚至可能不再存在于内存中,导致一种“悬空函数指针”。正如在另一个答案中指出的那样,防止这些问题通常涉及额外的状态和处理,这些状态和处理对于许多常见场景来说可能是过大的。所以 std::function
默认情况下不会阻止它们:如果需要,您必须在顶部构建这些安全构造。许多 C++ 标准库可用作更高级别构造的构建 block ,但它们本身不一定处于该级别。
关于c++ - 调用期间自毁 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30155850/
自从学了C++之后,我时不时会用C++来联想一些其他编程语言(即Java)的一些特性。这可能是因为我根本没有 100% 信任它们(我认为 100% 信任任何东西都是愚蠢的),而关于 JFrame 的东
所以我找到了这段代码,它显然可以工作(因为它已经投入生产多年了): window[someMethod] = function (tmp) { callback({prop:"val"}, t
我正在寻找设计自毁 Cocoa 应用程序的方法。这个想法是在启动时检测应用程序是否正在进行逆向工程(这总是在多次尝试中完成)并在情况下删除/损坏它。当然,狂热的黑客可以重新下载并逆向设计破坏过程,但这
在学习 C++ 的过程中,我偶然发现了文章 Writing Copy Constructors and Assignment Operators它提出了一种机制来避免复制构造函数和赋值运算符之间的代码
所以我有这个 fiddle here它在右下角添加一个 div 以在用户添加元素时通知用户(单击事件 item1..item5 div)。此 div 在几秒钟后自毁 (div.remove())。 $
我是一名优秀的程序员,十分优秀!