QObject: introduce QT_NO_CONTEXTLESS_CONNECT
The 3-arguments overload of connect() is error-prone / easy to misuse: * it's easy to e.g. connect to a lambda, and capture local state in the lambda. By not passing a receiver/context, the connection won't get disconnected if the local state gets destroyed (effectively, it creates a "dangling connection"); * in a multithread scenario, one may not realize that the connection is forced to be direct. If the signal is emitted in another thread than the one establishing the connection¹, then the functor will be invoked in that other thread. (Not that "the thread establishing the connection" has ever mattered, but again, this API is error-prone.) Add a macro that allows users to disable the overload in their project. I'm not going for deprecation because there's simply too much code around that uses it. [ChangeLog][QtCore][QObject] Added the QT_NO_CONTEXTLESS_CONNECT macro. Defining the macro before including any Qt header will disable the overload of QObject::connect that does not take a receiver/context argument. Change-Id: I86af1029c1a211ea365f417aae9038d3fcacadfd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
7297cd808b
commit
842cfcec80
|
|
@ -4854,6 +4854,28 @@ QDebug operator<<(QDebug dbg, const QObject *o)
|
|||
\sa QObject::connect
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro QT_NO_CONTEXTLESS_CONNECT
|
||||
\relates QObject
|
||||
\since 6.7
|
||||
|
||||
Defining this macro will the overload of QObject::connect() that
|
||||
connects a signal to a functor, without also specifying a QObject
|
||||
as a receiver/context object (that is, the 3-arguments overload
|
||||
of QObject::connect()).
|
||||
|
||||
Using the context-less overload is error prone, because it is easy
|
||||
to connect to functors that depend on some local state of the
|
||||
receiving end. If such local state gets destroyed, the connection
|
||||
does not get automatically disconnected.
|
||||
|
||||
Moreover, such connections are always direct connections, which may
|
||||
cause issues in multithreaded scenarios (for instance, if the
|
||||
signal is emitted from another thread).
|
||||
|
||||
\sa QObject::connect, Qt::ConnectionType
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QObjectList
|
||||
\relates QObject
|
||||
|
|
@ -4959,6 +4981,11 @@ void qDeleteInEventHandler(QObject *o)
|
|||
However, you should take care that any objects used within the functor
|
||||
are still alive when the signal is emitted.
|
||||
|
||||
For this reason, it is recommended to use the overload of connect()
|
||||
that also takes a QObject as a receiver/context. It is possible
|
||||
to disable the usage of the context-less overload by defining the
|
||||
\c{QT_NO_CONTEXTLESS_CONNECT} macro.
|
||||
|
||||
Overloaded functions can be resolved with help of \l qOverload.
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ public:
|
|||
type, types, &SignalType::Object::staticMetaObject);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONTEXTLESS_CONNECT
|
||||
//connect without context
|
||||
template <typename Func1, typename Func2>
|
||||
static inline QMetaObject::Connection
|
||||
|
|
@ -242,6 +243,7 @@ public:
|
|||
{
|
||||
return connect(sender, signal, sender, std::forward<Func2>(slot), Qt::DirectConnection);
|
||||
}
|
||||
#endif // QT_NO_CONTEXTLESS_CONNECT
|
||||
#endif //Q_QDOC
|
||||
|
||||
static bool disconnect(const QObject *sender, const char *signal,
|
||||
|
|
|
|||
Loading…
Reference in New Issue