Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt signals/slots: Is it an error to emit a signal from a temporary object?

In Qt, if a signal is called from a temporary object, such that the object may be deleted by the time the slot is called, is it an error?

In case it's relevant, the code is emitting the signal from the temporary object's constructor.

(Note: there are no pointers or references being passed as an argument, so this is not a question regarding dangling pointers or references. I just want to know if, in its simplest form, it is acceptable to emit a signal from a temporary object in Qt.)

Here is a shortened version of my code:

// My application
class HandyApplication: public QApplication
{
    Q_OBJECT
    public:
        explicit HandyApplication( int argc, char * argv[] );

    signals:

    public slots:
        void handySlot(std::string const msg);

};

// Class that will be instantiated to a temporary object
class Handy: public QObject
{
    Q_OBJECT

    public:

        Handy()
        {
            QObject::connect(this, SIGNAL(handySignal(std::string const)), 
                 QCoreApplication::instance(),
                 SLOT(handySlot(std::string const)));

            emit handySignal("My Message");
        }

    signals:

         void handySignal(std::string const msg);

};

// An unrelated function that may be called in another thread
void myFunction()
{
    Handy temporaryObject; // This constructor call will emit the signal "handySignal" above
}

As you can see, the temporary object emits the signal from its constructor, and is then destroyed immediately. Therefore, the slot may be called AFTER the object that sent the signal is destroyed.

Is this safe, or is this a potential problem or error condition?

like image 567
Dan Nissenbaum Avatar asked May 18 '13 03:05

Dan Nissenbaum


2 Answers

What you have specified would be a direct connection from the signal to the slot. That means at the moment you emit handySignal, it should go and execute all of the connected slots. Once all the slots (ie. handySlot) have returned, then the emitter will return and finish with the constructor.

If you were to specify a queued connection, as would be used if it were a connection from a signal in one thread, to a slot in another thread, then the request would be placed into the event loop to be executed.

So I would say: Yes it seems fine to emit a signal from an temporary object, if you are not passing along references that will be invalid.

The example seems a bit arbitrary, as I don't really see a point to making a connection in the constructor to a signal, which you then emit, and thats it. You might as well just call that slot, unless you are expecting the object to be created in a different thread, which you didn't mention.

Edit:

As per the comment by @Kamil, it should be noted that if a connection type is not specified, then the defailt with be an AutoConnection, which means the actual type will be determined by whether the target slot is in a different thread than the sender. Without threading, it would equate to a DirectConnection. With threading, it would end up being a QueuedConnection.

like image 116
jdi Avatar answered Oct 03 '22 06:10

jdi


I would say emitting from a temporary object is safe as QObject::destroyed "is emitted immediately before the object obj is destroyed" -Qt docs

So presumably signals emitted from a temporary object would be safe and proper.

like image 40
jtooker Avatar answered Oct 03 '22 06:10

jtooker