static bool QObject::disconnect(const QMetaObject::Connection &connection)
This method is meant to disconnect an existing Connection
object with intention to modify it. So why is the function argument declared as a const
reference?
In the source code implementation (qtbase/src/corelib/kernel/qobject.cpp
), you can find the unavoidable const_cast
:
const_cast<QMetaObject::Connection &>(connection).d_ptr = 0;
What is the advantage of marking the function argument as const
when the function's purpose is to modify it?
The reasons are purely historical. The API, as originally conceived, was thought not to need to modify the Connection
instance while disconnecting it. This has proven to be ill-conceived indeed. Binary compatibility reasons forced the API to remain unchanged. Neither the const-removal in the argument type nor mutable-addition in the field type would be binary-compatible changes. Relevant excerpt:
You cannot [...] For existing classes [...] For existing functions of any type [...] change its signature. This includes [...] changing any of the types of the arguments in the parameter list, including changing the const/volatile qualifiers [...]
You cannot [...] For non-static members [...] change the type of the member, except for signedness [...]
The original implementation of the new disconnect API did not modify the d_ptr
. This caused a memory leak when the Connection
instance outlived the sender object. The fix had to modify the Connection
's non-mutable fields, and this const_cast
was the only way to do it.
The original implementation is from 2011, and predates Qt 5 release, but the fix went into Qt 5.0.1, in 2012: at that point the binary compatibility had to be retained.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With