Nominate our 2022 Qt Champions!

why QMetaObject::invokeMethod() still construct object when reference is used as input parameter?

  • I have the following call in worker thread to invoke function call A in main thread. I notice QMetaMethod::invoke() calls QMetaType::construct(), and this function will call class B constructor. And later once it's done, destructor is called in main thread. Why is it even input parameter is reference?

         @ QMetaObject::invokeMethod(this, "A", Qt::QueuedConnection,
            Q_ARG(const B &, b));@

  • That's how queued signals and slots work. It is unsave to share the same instance of an object between two threads, unless that object makes very strong guarantees about that. Note that the reference part of the parameter is even stripped out of the signature for the signals and slots.

  • Andre, thanks for the info. But how about parameter is a pointer? I have another queued signal slot connection where signal function A and slot function B are using object C pointer as input parameter. I stepped in but seems no constructor is called..

    The code is like:

        @connect(workerThreadObject_ptr, SIGNAL(A(C *)), mainThreadObject_ptr, SLOT(B(C *)));@

  • Nope, pointer are passed as-is: a pointer.

  • So in this case, it may have safety issue.

  • Safety issue? How so?

    No more than if you pass a pointer to an object with a normal method call, and we do that all the time. Of course, you should not pass a pointer to a different thread to an object that is about to be destroyed or run out of scope. If you just want your thread to create an object, and then pass it to another thread, you could consider using a [[doc:QSharedPointer]] instead. You can pass those between threads, and you can be sure the object will not be destroyed before your receiving thread gets the handle to it.

Log in to reply