A quick experiment shows that the second slot is not called.
However, I'm not sure if this is something that Qt promises.
Qt does document that certain checks are made during the iteration of connected receivers, but it's but that's pretty loose and non-specific (and I haven't come across anything better in my short search); from http://doc.qt.io/qt-5/signalsandslots.html:
This is the overhead required to locate the connection object, to safely iterate over all connections (i.e. checking that subsequent receivers have not been destroyed during the emission)
So they loosely document that certain checks are made while a signal is emitted, such as whether a receiver has been destroyed. I think checking whether the connection has been disconnected seems like a similar kind of situation, but it would be nice if that were explicitly documented.
Since it sounds like this will be a problem for you (you want all the signals to get through, right?), you may be able to work around this problem by ensuring that the signal to slot b1()
is connected last. Qt does promise that slots will be called by a signal in connection order, so if you arrange for the slot that does the disconnect to be the last one, all the other slots will be seen.
I don't know how easy this might be to arrange, but it also seems kind of strange that an object would disconnect everything from inside another object's slot function (so there's probably some other refactoring that can solve this problem as well).
If none of that is acceptable, it wouldn't be too hard to come up with a proxy object for A
's signals that has the behavior you need. There would be a single:
connect(A, SIGNAL(a()), proxy_obj, SLOT(proxy_slot()));
to connect A's signal to the proxy, then B
can connect to the proxy's signal (which the proxy would be emit when the proxy's slot got called):
connect(proxy_obj, SIGNAL(a()), B, SLOT(b1()));
connect(proxy_obj, SIGNAL(a()), B, SLOT(b2()));
Since A's disconnect will not affect the connections that the proxy has to B, the proxy will ensure that all of B's slots get called when signal A->a()
is emitted.
class A_proxy : public QObject
{
Q_OBJECT
public slots:
void proxy_slot() {
emit a();
}
signals:
void a();
};