[Development] RFC: RAII for property changes

Andre Somers andre at familiesomers.nl
Wed Apr 15 18:29:33 CEST 2015


On 15-4-2015 17:08, Matthew Woehlke wrote:
> On 2015-04-15 10:43, Marc Mutz wrote:
>> On Wednesday 15 April 2015 11:49:56 André Somers wrote:
>>> void MyClass::setFoo(QString value)
>>> {
>>>     PropertyGuard guard(this, "foo");  //foo is the name of the Q_PROPERTY
>>>     Q_UNUSED(guard);
>>>
>>>     m_foo = value;
>>> }
>> This is an interesting idea, though I don't think I have encountered the
>> problems with which you motivate PropertyGuard.
>>
>> For use in a library, though, I fear the string-based mechanism is too
>> inefficient. For use within QtWidgets, say, I'd suggest a mechanism that works
>> on the member data directly.
> FWIW I had the same thought; also, I'm not a fan of needing the
> Q_UNUSED, or using a macro to 'hide' it.
>
> 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 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.

I also don't like using a macro much, but it does yield quite an elegant 
way to say what you want I think. It also hides the explicit reference 
to this. You can still use the explicit way too of course, especially if 
you want to access the guard object afterwards (you can cancel it and 
access the original value for instance).

I am currently not seeing a need to trigger anything else than the 
notification signal, but I guess that could be added if there is a need 
for that.

André






More information about the Development mailing list