[Development] RFC: RAII for property changes

André Somers andre at familiesomers.nl
Wed Apr 15 16:58:24 CEST 2015


Hi Marc,

Thank you for responding.

Marc Mutz schreef op 15-4-2015 om 16:43:
> Hi André,
>
> 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.
Are you sure, or is your code just not secure? ;-)

Basically, if you have this code (or something like it) somewhere, you 
already have a problem:

void MyClass::setFooAndBar(QString foo, int bar)
{
   if (m_foo != foo) {
     m_foo = foo;
     emit fooChanged(foo);  //this is where things may start to go wrong 
already
   }

   if (m_bar != bar) {
     m_bar = bar;
     emit barChanged(bar);
   }
}

Calling separate setters instead from inside setFooAndBar doesn't help.

What happens if a slot connected to fooChanged uses the instance of 
MyClass? What property values does it see? foo is changed, but bar has 
not changed yet. What if that slot triggers something that ends up 
deleting the instance?

You'd have to write something like this instead:

void MyClass::setFooAndBar(QString foo, int bar)
{
   bool fooHasChanged(false);
   bool barHasChanged(false);

   if (m_foo != foo) {
     m_foo = foo;
     fooHasChanged = true;
   }

   if (m_bar != bar) {
     m_bar = bar;
     barHasChanged = true;
   }

   if (fooHasChanged) emit fooHasChanged(foo);
   if (barHasChanged) emit barHasChanged(bar); // we should check if 
we're still alive before we do this
}

I find my version easier to write and maintain:

void MyClass::setFooAndBar(QString foo, int bar)
{
   guardProperty(foo);
   guardProperty(bar);

   m_foo = foo;
   m_bar = bar;
}


>
> 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.
I developed this still working on Qt4, and there its's all we have. Do 
you have a suggestion how to get access to the metaproperty without 
using the string lookup in Qt5? AFAIK, that is still string-based API. 
Perhaps it could be a constexpr though, as the value really wouldn't 
change at runtime (for normal C++ objects, not talking about dynamic 
generated stuff here)? I doubt that will actually work, but I have not 
played around with that enough yet.

Thanks for your comments though; speed is a real concern of course.

André




More information about the Development mailing list