【问题标题】:Best optimisation for Signals/Slots with Qt使用 Qt 对信号/插槽进行最佳优化
【发布时间】:2016-01-17 15:34:49
【问题描述】:

如果我拿,两个这样的物体:

firstobject.h:

public slots:
    void h_doSomething(int someint, std::vector<int> somevector, bool somebool); //(int)vector.size(): 80;

firstobject.cpp:

void firstobject::h_doSomething(int someint, std::vector<int> somevector, bool somebool)
{
    emit anotherSignal(someint+4, somebool, somevector);
}

secondobject.h:

public signals:
        void doSomething(int someint, std::vector<int> somevector, bool somebool); //(int)vector.size(): 80;
private:
    std::vector< int > m_somevector;

secondobject.cpp:

void secondobject::basicFunction()
{
    emit doSomething(51, m_somevector, true);
}

那些信号和槽是相连的,这些槽和信号的最佳优化是什么?

对于插槽,我想应该是:

void h_doSomething(const int &someint, const std::vector<int> &somevector, const bool &somebool) const;

但是对于我不知道的信号,我认为向量需要被复制,因为它是一个受保护的变量。

【问题讨论】:

  • 见this。
  • 您可以将向量作为 const ref 传递。在信号中,也是。 protected/private 与此无关(如果有,编译器会通过失败告诉你)。通过 const ref 将 POD 类型作为 int 和 bool 传递。不过没有任何意义。

标签: c++ qt


【解决方案1】:

我想说总是通过const 引用传递复杂的对象,除非你有很好的理由不这样做。对于像 int 和 bool 这样的原始类型,通常最好按原样传递它们。

您需要了解的是,信号和插槽都只是函数。信号有点特殊,因为您自己没有实现它,MOC 会这样做。但它仍然只是一个功能!通过使用const,您可以避免不必要的复制,这即使对于共享类也是一件好事,但在复制占用大量资源时尤其有用,例如vector。

这里很重要的一点是,信号槽连接有两种形式:直接连接和排队连接。对于直接连接信号,基本上直接调用所有连接的插槽,所以当你这样做时

emit doSomething(51, m_somevector, true);

它只是调用连接的插槽并将参数传递给它们。

对于排队的连接,Qt 会复制参数,将它们排队并稍后在另一个线程中调用插槽。即使您声明传递引用,也会制作副本,因此仍然可以正常工作。

这确实没有理由按值传递复杂对象,除非在调用过程中存在对象发生某些事情的风险。例如,可能是某个槽对向量进行迭代,并且在迭代期间调用了一些修改向量的方法。这可能会破坏迭代过程。但即便如此,您也可以在该方法内迭代一个副本,并仍然根据您的需要通过引用传递参数。或者只是重新设计整个事物以避免此类修改。

【讨论】:

  • 感谢您的明确答复!我可以直接连接,因为我会在处理和禁用所有其他用户输入时使用加载栏阻止 GUI。
  • @Ticki,这通常是个坏主意。您不仅会以这种方式阻止输入,还会阻止重新绘制,使其看起来像挂起。当然,您可以不时调用QApplication::processEvents 来防止这种情况发生……或者使用专用线程并通过模式对话框或其他方式阻止GUI。您的来电。
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 2021-08-28
  • 2012-08-09
  • 2020-10-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多