【问题标题】:Using CallAfter to call wxWindow::Destroy generates compile-time error使用 CallAfter 调用 wxWindow::Destroy 会产生编译时错误
【发布时间】:2017-01-10 00:21:16
【问题描述】:

我正在尝试销毁一个 wxWindow 派生对象,该对象可能已受到来自其容器对象之一的 Bind() 的影响。根据我的阅读(以及一些之前追逐奇怪错误的经验),我相信我需要延迟对 Destroy() 的调用,直到事件队列用尽之后,否则事件处理程序可能会尝试访问被破坏的对象。

我一直在阅读的内容是使用 CallAfter() 来执行对象的 Destroy() 函数。问题是,如果我打电话

obj->CallAfter(&ObjClass::Destroy);

我收到一个编译错误“C2064 术语不计算为采用 0 个参数的函数”,指向 wx/event.h 中的 wxAsyncMethodCallEventFunctor::Execute() 函数。这对我来说似乎很奇怪,因为 wxWindow::Destroy() 没有参数;我认为可能是实例引用(“obj”)是问题所在,但是当我尝试将其插入调用其他方式时,我收到错误说我有太多参数。

通过一些实验,我已经能够通过在我的派生对象中定义一个函数来使其工作,该函数接受 0 个参数并且(显然很关键)返回 void 而不是 bool。喜欢:

void ObjClass::DestroyMe()
{
    this->Destroy();
}

现在,当我使用表达式时

obj->CallAfter(&ObjClass::DestroyMe);

程序编译并且似乎正在运行。尽管如此,我还是讨厌这个解决方案,因为它感觉很笨拙。

  • 有更好的方法吗?

  • 我认为这个问题与 bool 与 void 有关是否正确 返回值?

    • 如果是这样,我能否以某种方式对函数引用进行类型转换以模拟 void() 函数调用(因为我不关心 bool 值)?

【问题讨论】:

  • 为什么不在关闭窗口之前 unbind() 所有这些处理程序,或者在窗口析构函数中更好?
  • 我必须深入研究事件表以逐个确定绑定是什么,这肯定需要比我已经构建的代码更多的代码;我的目标是降低复杂性。

标签: c++ wxwidgets


【解决方案1】:

CallAfter() 确实期望 void 可调用,因为如果它拿走任何东西然后丢弃结果会很危险(因为它还能用它做什么?),所以你不能通过它Destroy()直接。

您的解决方法很好,但是,当然,在 C++11 中,您可以通过使用与 CallAfter() 配合得很好的 lambda 来使其更短更方便,所以通常您只需编写

obj->CallAfter([=]() { this->Destroy(); });

【讨论】:

  • 谢谢。我认为我真正需要做的是学习 lambda;我从来没有使用过它们(据我所知,当我学习 C++ 时它们并不存在),直到现在我从来没有觉得有太多需要了解它们。
猜你喜欢
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 2019-10-24
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多