发布于 2016-09-02 00:00:49
我希望信号不会修改发送者
信号(如由MOC生成)不直接修改类实例的成员。但是,生成的代码传递一个this指针,以供(潜在的)槽使用。因此,连接的插槽可以使信号的发送方发生突变。
因此,技术原因是,如果信号是const,则需要所有时隙实现只调用发送方上的const类成员,代码才能编译而不出现错误。
在代码安全方面,将信号实现为非const类成员是一个可以理解的决定。在许多情况下,这仍然是不自然的(例如,如果在同一个类中实现的连接槽是const,或者连接的槽完全属于另一个对象)。
发布于 2017-10-26 12:09:36
Nothing阻止Qt信号成为const (用Qt5.9测试)。来自IInspectable的答案是不正确的。
下面是我做的一个测试,以证明它仍然有可能
sender()上的非const方法。我的考试课,编译得很好(gcc):
// 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为信号生成的代码:
// 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方法中发出它们一样。你可以自由地这么做。
发布于 2018-10-04 19:42:34
信号可以是const,实际上,如果您想从const函数发出信号,它必须是const信号,但是在插槽端,它不需要是const。在用const pures重新实现抽象类时,我已经摆脱了以这种方式使用可变的情况。
https://stackoverflow.com/questions/39281740
复制相似问题