首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Qt信号不是康斯特?

问为什么Qt信号不是康斯特?
EN

Stack Overflow用户
提问于 2016-09-01 22:21:12
回答 3查看 5.9K关注 0票数 20

Qt使用信号和插槽进行对象通信。信号通常被声明为成员函数,Qt然后生成该函数的定义。

我想了解的是,为什么信号不是const成员函数?

编辑:我希望信号不会修改发送者,这就是问题的原因。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-02 00:00:49

我希望信号不会修改发送者

信号(如由MOC生成)不直接修改类实例的成员。但是,生成的代码传递一个this指针,以供(潜在的)槽使用。因此,连接的插槽可以使信号的发送方发生突变。

因此,技术原因是,如果信号是const,则需要所有时隙实现只调用发送方上的const类成员,代码才能编译而不出现错误。

在代码安全方面,将信号实现为非const类成员是一个可以理解的决定。在许多情况下,这仍然是不自然的(例如,如果在同一个类中实现的连接槽是const,或者连接的槽完全属于另一个对象)。

票数 15
EN

Stack Overflow用户

发布于 2017-10-26 12:09:36

Nothing阻止Qt信号成为const (用Qt5.9测试)。来自IInspectable的答案是不正确的。

下面是我做的一个测试,以证明它仍然有可能

  • 将const信号连接到同一实例中的非const槽。
  • 调用sender()上的非const方法。

我的考试课,编译得很好(gcc):

代码语言:javascript
复制
// Stupid class to test the emit of a const-signal
class Test : public QObject
{
    Q_OBJECT

public:
    // Connect in the constructor from this instance to this instance
    explicit Test(QObject *parent = nullptr) : QObject(parent) {
        connect(this, &Test::valueChanged, this, &Test::updateString);
    }

    // To test a non-const method call
    void nonConstFoo() {
        setObjectName("foo"); // I modify the 'this' instance
    }

    // To test emit of a non-const signal from a const-method
//    void constFoo() const {
//        emit fooSignal(); // --> FAIL at compile time
//    }

public slots:
    void setValue(int value) {
        m_value = value;
        emit valueChanged(value);
    }

    void updateString(int value) {
        m_string = QString::number(value); // I modify the 'this' instance
        nonConstFoo(); // I modify the 'this' instance through a non-const call

        auto s = sender();
        s->setObjectName("mutated name"); // I modify the 'sender' instance

        qDebug() << "Updated string" << m_string;
    }

signals:
    void valueChanged(int) const; // The signal is const
    void fooSignal(); // Non-const signal

private:
    int m_value;
    QString m_string;
};

下面是MOC为信号生成的代码:

代码语言:javascript
复制
// SIGNAL 0
void Test::valueChanged(int _t1)const
{
    void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(const_cast< Test *>(this), &staticMetaObject, 0, _a);
}

// SIGNAL 1
void Test::fooSignal()
{
    QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}

我们可以看到,Qt在这方面使用了const_cast,所以一切都会正常工作。

在我看来,默认情况下信号不是const的原因是,这将要求MOC在您的信号(==类-方法)定义中添加const,从而修改源代码。

我想这是可以做到的,将每一个定义的信号在一个宏,但想象一下痛苦的编码器和读者。我不认为Qt (或您)有任何收益,您的信号声明为const,这将需要您和Qt更多的工作。

,但,有时您可能需要将它们声明为const。就像您想从const方法中发出它们一样。你可以自由地这么做。

票数 9
EN

Stack Overflow用户

发布于 2018-10-04 19:42:34

信号可以是const,实际上,如果您想从const函数发出信号,它必须是const信号,但是在插槽端,它不需要是const。在用const pures重新实现抽象类时,我已经摆脱了以这种方式使用可变的情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39281740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档