C++ 在接收器对象销毁时未调用Qt disconnectNotify()

C++ 在接收器对象销毁时未调用Qt disconnectNotify(),c++,qt,C++,Qt,我有一个C类发射信号S。S可以连接到零个或多个接收器(R)(连接的数量随时间而变化,并且由接收器连接W) C需要在S的侦听器数量大于零时执行一些操作,并且在S的侦听器数量回到零时执行其他操作 我想我可以用: connectNotify() 及 嗯 我注意到的是connectNotify()函数工作得很好,但是当接收对象被销毁时,disconnectNotify()没有被调用(在类C中)。只有在使用显式断开连接(使用disconnect())时,才会调用它 在侦听器的析构函数中添加显式断开连接也

我有一个C类发射信号S。S可以连接到零个或多个接收器(R)(连接的数量随时间而变化,并且由接收器连接W)

C需要在S的侦听器数量大于零时执行一些操作,并且在S的侦听器数量回到零时执行其他操作

我想我可以用:

connectNotify()

我注意到的是connectNotify()函数工作得很好,但是当接收对象被销毁时,disconnectNotify()没有被调用(在类C中)。只有在使用显式断开连接(使用disconnect())时,才会调用它

在侦听器的析构函数中添加显式断开连接也不是很成功:退出整个应用程序时出现分段错误。(我想当一切都发生故障时,尝试使用disconnect()不是很好。)

当R被销毁时,我尝试使用从R实例发送到C的destroy()信号:这是可行的,但我如何确保R在销毁时已连接?(接收器R可能存在于非连接状态):

在C类中,插槽X(在接收R的destroyed()时调用)检查QObject::receivers(),似乎返回执行销毁之前的接收器数量。因为我不知道被摧毁的物体是否连接,我被卡住了


有什么想法吗?

如果您能确保在C之前销毁所有R,您可以自己在C类中管理连接:

头文件:

#include <QtCore/QSet>

class C : (...)
{
    (...)

public:
    void connectReceiver( QObject* receiver );

private slots:
    void handleReceiverDestruction( QObject* receiver );

private:
    QSet< QObject* > _connectedReceivers;
};

我在一个测试应用程序中得到了同样的行为;对我来说,这似乎与文档不一致。你在析构函数中显式断开连接的想法对我很有效,但是你程序中的破坏顺序可能会把事情搞砸。我很想知道,当信号接收器被破坏时,是否有其他人可以得到一个
disconnectNotify
。这在Qt 5中是固定的。看,谢谢,这和我想做的工作非常接近。我还不时检查QOBject::receivers(),因为当接收器被销毁时,QOBject::receivers()似乎会递减(但这是在接收到C中销毁的()信号后发生的)。它们有很多可能的解决方法,但我仍然觉得disconnectNotify的行为很奇怪,再次感谢!
#include <QtCore/QSet>

class C : (...)
{
    (...)

public:
    void connectReceiver( QObject* receiver );

private slots:
    void handleReceiverDestruction( QObject* receiver );

private:
    QSet< QObject* > _connectedReceivers;
};
void C::connectReceiver( QObject* receiver  )
{
    // nothing to do if the receiver is already connected
    if( _connectedReceivers.contains( receiver  ) ) return;

    _connectedReceivers.append( receiver )

    connect( ... ); // <- do your connection(s) here
    connect( receiver, SIGNAL( destroyed                ( QObject* ) ), 
             this    , SLOT  ( handleReceiverDestruction( QObject* ) ) );
}

void C::handleReceiverDestruction( QObject* receiver )
{
    if( !_connectedReceivers.contains( receiver ) )
    {
        // if this happens, a receiver R's destroyed() signal was connected to
        // this function altough R is not a receiver of signal X.
        Q_ASSERT( false );
        return;
    }

    disconnect( ... ); // <- one or more might be necessary here

    _connectedReceivers.remove( receiver );
}
C::~C()
{
    if( !_connectedReceivers.isEmpty() )
    {
        // If you land here, a receiver was not (properly) destroyed before this object
        Q_ASSERT( false );
    }
}