为什么信号和插槽比普通的旧回调更好?

詹姆斯·高

这里的C ++新手。我在读《信号和插槽的更深入的了解》,它声称1)回调本质上是类型不安全的,2)为了使它们安全,您需要在函数周围定义一个纯虚拟类包装器。我很难理解这是真的。例如,这是Qt在其教程页面上提供的信号和插槽代码

// Header file
#include <QObject>

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }

public slots:
    void setValue(int value);

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

// .cpp file
void Counter::setValue(int value)
{
    if (value != m_value) {
        m_value = value;
        emit valueChanged(value);
    }
}

// Later on...
Counter a, b;
QObject::connect(&a, SIGNAL(valueChanged(int)),
                 &b, SLOT(setValue(int)));

a.setValue(12);     // a.value() == 12, b.value() == 12
b.setValue(48);     // a.value() == 12, b.value() == 48

这是使用回调重写的代码:

#include <functional>
#include <vector>

class Counter
{
public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }
    std::vector<std::function<void(int)>> valueChanged;

    void setValue(int value);

private:
    int m_value;
};

void Counter::setValue(int value)
{
    if (value != m_value) {
        m_value = value;
        for (auto func : valueChanged) {
            func(value);
        }
    }
}

// Later on...
Counter a, b;
auto lambda = [&](int value) { b.setValue(value); };
a.valueChanged.push_back(lambda);

a.setValue(12);
b.setValue(48);

如您所见,回调版本是类型安全的,并且比Qt版本短,尽管他们声称不是除了,它没有定义任何新类Counter它仅使用标准库代码,不需要特殊的编译器(moc)即可工作。那么,为什么信号和插槽优先于回调呢?C ++ 11是否简单地淘汰了这些概念?

谢谢。

德泰

为什么信号和插槽比普通的旧回调更好?

因为信号很像普通的旧回调,所以除了具有额外的功能并与Qt API深度集成之外。它不是火箭科学-回调+附加功能+深度集成比单独的回调要强大。C ++可能最终会提供一种更干净的回调方法,但这并不能取代Qt信号和插槽,更不用说使它们过时了。

自从Qt 5以来,插槽方面就变得不那么重要了,它可以将信号连接到任何功能。但是,插槽仍与Qt元系统集成,许多Qt API使用该系统来使工作正常进行。

是的,您几乎可以使用回调来实现信号应该实现的所有功能。但这并不容易,它有点冗长,它不会自动处理排队的连接,它不会像信号那样与Qt集成,您可能也可以解决它,但是它将变得更加冗长。

对于QML来说,Qt是当今的主要关注点,但实际上您对Qt的信号感到困惑。因此,我认为信号会持续存在。

信号和插槽“更好”,因为Qt在概念上围绕它们而构建,它们是API的一部分,并且被许多API使用。这些概念已经存在于Qt中很长时间了,从C ++过去,它除了提供从C继承来的简单的旧函数指针外,没有提供太多的回调支持。这也是Qt不能简单地切换到std回调的原因-它会打破很多东西,这是不必要的努力。同样的原因,Qt继续使用那些邪恶的,不安全的普通旧指针而不是智能指针。信号和插槽并不是一个过时的概念,在使用Qt时,从技术上讲也是如此。C ++太晚了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么addEvenetListener上的回调输出旧状态?

来自分类Dev

为什么较旧的CPU性能更好?

来自分类Dev

为什么Angular.js Promise比JavaScript中的回调更好

来自分类Dev

为什么我的Qt信号/插槽断点没有命中?(信号/插槽)

来自分类Dev

Qt 中的普通函数和插槽有什么区别?

来自分类Dev

信号和插槽的工作

来自分类Dev

信号和插槽 qt 关闭插槽

来自分类Dev

为什么我的WCF回调超时?

来自分类Dev

为什么回调未定义?

来自分类Dev

为什么我的回调不是函数?

来自分类Dev

为什么回调不起作用?

来自分类Dev

Qt信号和插槽:权限

来自分类Dev

Qt插槽和信号语法

来自分类Dev

Qt信号和插槽故障

来自分类Dev

插槽和信号无限循环

来自分类Dev

带信号和插槽的QScopedPointer

来自分类Dev

使用Passport和ExpressJS的Facebook身份验证-为什么未调用验证回调?

来自分类Dev

为什么普通的类方法可以用作Qt中的插槽?

来自分类Dev

当连接的插槽显示QMessageBox时,为什么editFinished信号会生成两次?

来自分类Dev

为什么这个PyQt5 Qlistwidget信号+插槽不起作用?

来自分类Dev

为什么QDialog中发出的信号无法调用QThread中连接的插槽?

来自分类Dev

为什么有些“普通的旧Ruby对象”进入app / models目录而不是lib direcory?

来自分类Dev

std :: function不起作用,但是普通的旧函数指针起作用-为什么?

来自分类Dev

Qt插槽和信号。获取插槽接收器对象

来自分类Dev

可以多次链接信号和插槽吗?

来自分类Dev

QT5中的信号和插槽

来自分类Dev

Qt:连接文本中的信号和插槽

来自分类Dev

Qt信号和插槽传递数据

来自分类Dev

PyQt4信号和插槽-QToolButton

Related 相关文章

热门标签

归档