Mac*_*Mac 9 c++ qt signals-slots
Qt使用信号和插槽进行对象通信.信号通常被声明为成员函数,然后Qt MOC生成该函数的定义.
我想了解的是为什么信号不是const成员函数?
编辑:我希望信号不会修改发件人,这就是问题的原因.
IIn*_*ble 10
我希望信号不会修改发件人
信号(由MOC生成)不直接修改类实例的成员.然而,生成的代码传递this指针,以供(潜在)时隙消耗.因此,连接的插槽可以改变信号的发送方.
因此技术原因是,如果信号是const,则需要所有插槽实现仅调用const发送方上的类成员以使代码编译而没有错误.
const在代码安全方面,将信号实现为非类成员是一个可以理解的决定.在许多情况下,它仍然感觉不自然(例如,如果连接的插槽在同一类中实现const,或者连接的插槽完全属于另一个对象).
没有什么可以阻止Qt信号成为AFAIK常量(已通过Qt5.9测试)。IInspectable的答案不正确。
下面是一个测试,我做表明它仍然是可能的
-一个连接常量信号到非const槽在同一个实例
-调用非const方法上sender()。
我测试的类,可以编译良好(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;
};
Run Code Online (Sandbox Code Playgroud)
这是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);
}
Run Code Online (Sandbox Code Playgroud)
我们可以看到Qt 对此使用了const_cast,因此一切都会正常进行。
在我看来,这些信号是不是常量默认的原因是,这将需要建设部一个const添加到您的信号(==类方法)定义你的头,因此修改源代码。
我想这可以通过将每个信号定义放在一个宏中来实现,但是可以想象一下编码人员和读者的痛苦。我看不到Qt(也不是您)将信号声明为const的任何收益(这对您和Qt都需要更多的工作)。
但是有时您可能需要将它们声明为const。就像您想从const方法中发出它们一样。您可以自由地这样做。