[Interest] Who disconnects lambda expression slots?

Thiago Macieira thiago.macieira at intel.com
Sat Dec 15 04:19:32 CET 2012


On sábado, 15 de dezembro de 2012 03.45.56, Nikos Chantziaras wrote:
> So I take it that means we should always manually disconnect in such
> cases.  Thinking about it, it seems possible to have done this
> automatically, but only for QObjects and through a connect() function
> that would accept:
> 
>      connect(const QObject* sender, PointerToMemberFunction signal,
>              const QObject* receiver, Functor functor);
> 
> In that case, connect() would be able to know when 'receiver' gets
> destroyed and automatically do a disconnect.

It automatically disconnects when the destruction reaches the QObject 
destructor. But the fact that you're even talking about disconnecting 
indicates that I did not express myself very well.

When the slot is called via the virtual, we're sure that the slot is called in 
a proper object. When calling via a functor, there's no such guarantee. Let me 
give you an example:

class Base: public QObject
{
    Q_OBJECT
public:
    ~Base()
    {
         emit signal();
    }
signals:
    void signal();
};

class Derived: public Base
{
     Q_OBJECT
public:
    Derived()
    {
         connect signal() to slot()
    }
public slots:
     void slot();
};

Note how the signal is emitted from the Base destructor. If you connect via 
the old method, the signal is emitted and then the qt_metacall virtual is 
called[*]. But since the object is no longer of type Derived, the call is 
routed through Base::qt_metacall and that does not call Derived::slot().

If you connect via the new method, there's no protection afforded by the 
virtual. That means it will call Derived::slot() *after* Derived's destructor 
has finished. The C++ standard probably says that it is undefined behaviour.

> Was something like this actually considered when designing the new
> connection mechanism?  Is it in any TODO list? :-)

It's impossible to do. We're giving you the rope. If you use it to hang 
yourself, it's your fault.


[*] actually, not really; that is the behaviour from 4.0 until 4.7 or so. In 
4.7 or 4.8, the behaviour was changed slightly to improve performance and pave 
the way to calling static functions. This protection mechanism was the hardest 
problem to solve.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20121214/4825e0d7/attachment.sig>


More information about the Interest mailing list