[Development] RFC: RAII for property changes

Matthew Woehlke mw_triad at users.sourceforge.net
Wed Apr 15 18:44:21 CEST 2015


On 2015-04-15 12:29, Andre Somers wrote:
> On 15-4-2015 17:08, Matthew Woehlke wrote:
>> What about something like this?
>>
>>    QPropertyGuard g{this};
>>    g.addProperty("a"); // use QObject::property
>>    g.addProperty("b", m_b); // take value member by reference
>>    g.addProperty(m_c, &cChanged); // ...and also slot address
>>
>> It's slightly redundant because declaring the guard and adding a
>> property are separate, but there is no unused object, and you can use
>> the same guard for multiple properties.
>>
>> The implementation is trickier (probably you need a dynamically
>> allocated templated helper class with a virtual base to store the value
>> and check for changes), but avoids multiple string-based look-ups.
>>
>> The "slot" could be a functor, like QObject::connect accepts, that could
>> be any of the actual slot, std::function, lambda, etc.
>
> I'm not sure I understand your solution, or what it yields over what I 
> am using now. Of course what I do is not using multiple string lookups. 
> The property is looked up once on construction of the guard object. Then 
> the current value is copied as a QVariant, as it is made available 
> through the property system. The signal meta-method is also stored from 
> the constructor, so the destructor can use it. So, only one 
> string-lookup needed per property. The elegance is that it uses the 
> property system to get the value *and* the notification signal to 
> trigger, so it is really easy to use.

The second form would thus save the value <-> QVariant comparison and
not much else. The third form however eliminates the string look-up
entirely by having the user provide both the backing member variable
*and* what to do when a change should be emitted. (I'd expect this to be
the change signal most of the time, but taking a functor adds the
flexibility of allowing users to do other things if needed.)

> The need for a Q_UNUSED is inherent in any RAII class that you don't 
> explicitly use any more. It works without, but you get a warning about 
> an unused variable which is annoying. QMutexLocker suffers from the same 
> problem.

"Yes", but separating the construction and property binding eliminates
that (because you "used" the guard after all) and allows one guard to
track multiple properties, with a potential saving in memory complexity.
The down side is that it's a little more typing, so it's a trade-off.

-- 
Matthew




More information about the Development mailing list