El dimarts, 24 de febrer del 2026, a les 15:57:39 (Hora estàndard d’Europa 
central), Ulf Hermann via Development va escriure:
> Greetings and Salutations,
> 
> As some of you may know, QMetaObject has a problem with what we call
> "shadowing". Consider:
> 
> class Base
> {
>      Q_OBJECT
>      Q_PROPERTY(int a READ a CONSTANT)
> 
> public:
>      int a() const { return 4; }
> 
>      Q_INVOKABLE int b() const { return 5; }
> };
> 
> class Derived : public Base
> {
>      Q_OBJECT
>      Q_PROPERTY(int a READ a CONSTANT) // shadows Base::a
> 
> public:
>      int a() const { return 6; }
> 
>      // Shadows Base::b
>      Q_INVOKABLE int b() const { return 7; }
> };
> 
> Now when you get a Base* and retrieve its property "a" or call its
> method "b" via the QMetaObject, you don't actually know which property
> you are retrieving or which method you are calling.
> 
>  From C++ you can introspect the QMetaObject hierarchy and determine
> what property or method you're dealing with. This is much more
> complicated than the usual way of simply doing
> someObject->property("a"), though.
> 
>  From QML, you can't. QML will always use the most-derived QMetaObject
> that has the property or method. You can shadow properties and methods
> further in QML, and most egregiously, you can shadow properties with
> methods and vice versa. This is rather dangerous because we internally
> rely on many of the properties of, say QQuickItem, to actually assume
> the values we set on them. If you shadow a property like
> QQuickItem::data, you're certainly in for some surprises. It is quite
> common to add a property called "data" to one of your custom types,
> though. So, this is inviting some serious foot archery. For fun and
> confusion, try the following:
> 
> // Base.qml
> import QtQuick
> Item {
>     id: root
>     property int data
> }
> 
> // Derived.qml
> import QtQuick
> Base{
>     Rectangle {}
> }
> 
> This results in the following warning:
> 
> Derived.qml:3:4: Cannot assign value of type "Rectangle" to property
> "data", expecting "int"
> 
> We've recognized this as a problem a long time ago and introduced the
> FINAL attribute to Q_PROPERTY. The FINAL attribute only takes effect if
> you use QML. If you shadow a FINAL property in pure C++, it does nothing
> (unfortunately). However, if you try to use a *shadowed* FINAL property
> in QML you get a warning or an error, depending on the context. We can't
> really do better than this for FINAL alone. You can call moc on Base and
> Derived independently, and you can re-moc Base after building Derived.
> This way you can sneakily introduce a FINAL after the derived type
> already exists. So we have to accept some fuzziness there. It follows
> that also in QML we can't flat out reject all your shadowed properties.
> We can just assume they are not shadowed and still use the base type's
> properties in case they are.
> 
> On top of all this complication, however, the presence of FINAL is not
> quite enough because you have to remember to add FINAL to every property
> that's eligible for finality. Keeping track of this is messy and
> error-prone. As a result, few properties are FINAL in practice, even if
> most should be.
> 
> C++, back in the day, had a similar problem with virtual methods. When
> you declared a method in a derived type, you'd have to look up all the
> methods in all base types to figure out if the method you were declaring
> was virtual by inheritance. This was error-prone. You could accidentally
> introduce overriding methods that weren't meant to be virtual and vice
> versa.
> 
> In C++, this was solved by introducing the "override" and "final"
> keywords to mark methods that are intentionally overriding a virtual
> one. The introduction of the "override" and "final" keywords came with a
> number of warnings and errors that now steer you towards adding the new
> keywords to all methods that intentionally override, and only those.
> 
> In Qt 6.11, we're doing the same to Q_PROPERTY. In addition to FINAL,
> you can now add attributes VIRTUAL and OVERRIDE to mark properties that
> are intended to be overridden and ones that intentionally override a
> virtual property. 

Can you give an example of why one would want a virtual/override property?

Is it to change the setter/getter function? Would that not better be solved 
making the setter/getter virtual on the C++ side and removing the "overriden" 
property?

Cheers,
  Albert

> Likewise, in QML you can mark properties with the
> "virtual", "override", and "final" keywords. If you use those new
> attributes and keywords, you get appropriate warnings and errors in QML
> (but not in C++, because see above). If you don't use them, you don't
> get warned ... yet. This is because we haven't adapted all of Qt to be
> free of those warnings, yet.
> 
> We still highly recommend you clean up unintended shadowing and use the
> new keywords and attributes where applicable already in Qt 6.11. You can
> get warned about shadowing properties without the new keywords and
> attributes by enabling debug messages from the
> qt.qml.propertyCache.append logging category. For example with an
> environment variable like this:
> 
> QT_LOGGING_RULES="qt.qml.propertyCache.append.debug=true"
> 
> For Qt 6.12, we are planning to enable these warnings by default. Among
> other things, this will mean that you will get warned when shadowing
> properties from Qt types that aren't meant to be shadowed.
> 
> In addition, we are planning to resolve the issue of shadowing methods
> and shadowing properties with methods in a similar way. We don't know
> when this will be ready, though.
> 
> best regards,
> Ulf




-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to