tufao  0.8.1
An asynchronous web framework for C++ built on top of Qt
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
Safe signals

We say that a signal is safe when it's safe to delete the object in the slot connected to this signal.

This property implies that no member-function will access the attributes of the object after emit the signal (and won't schedule such accesses).

Consider the following code:

void SomeObject::someMethod()
{
emit someSignal();
qDebug() << this->x;
}

In the previous code, someSignal is an unsafe signal, because there is accesses to the internal state of the object after it emits the signal. We can refactor the previous code to make someSignal safe by reordering. See the final version, where someSignal is safe:

void SomeObject::someMethod()
{
qDebug() << this->x;
emit someSignal();
}

Why do you wanna a safe signal? They are safer and you need to worry less about invalid access. Consider you have an object O – allocated on the heap – of type SomeObject and a method M connected to the signal someSignal, then the following code is valid:

class OurClass: public QObject
{
Q_OBJECT
public:
OurClass(SomeObject *O, QObject *parent) :
QObject(parent), O(O)
{
connect(&O, &SomeObject::someSignal, this, &OurClass::M);
}
void M()
{
delete O;
}
private:
SomeObject *O;
}

If you have an unsafe signal, your only choice is to use QObject::deleteLater.

Why some signals are unsafe

Sometimes, it's too complicated to create a safe signal. Consider you receive a message via the network and some method parse this message. Consider the method should emit signals each time a new message is ready, something like the code below:

void Foobar::slot()
{
QByteArray buf = socket->readAll();
while (buf.size()) {
// ...
if (/* ... */)
emit unsafeSignal();
// ...
}
}

The above code uses an unsafe signal. Sure you could convert the code to use safe signals, but the overhead of performance and responsiveness created wouldn't be worth.

Another example of an unsafe signal:

void Foobar::method()
{
// ...
emit conditionOneReady();
// ...
emit conditionTwoReady();
// ...
// The below signal is the only safe signal
emit finalConditionReady();
}

Conclusion

Every signal in Tuf√£o is safe, unless explicitly stated the opposite.

Warning
It's unsafe to delete an object in the body of a slot connected to an unsafe signal emitted by the same object.

Some alternative ways of deleting an object in code triggered by an unsafe signal are:

  • Call QObject::deleteLater
  • Use a Qt's Qt::QueuedConnection connection to make the connection between the unsafe signal and your slot
  • Queuing/delegating the responsability to somebody else
  • Use some well designed architeture on top of QSharedPointer or similar