Hi,

It seems that the presence of QWeakPointer::data() in the past has given many Qt developers the wrong impression and they're now fighting hard to keep that impression intact when porting away from deprecated data().

So here's some re-education. Ignore at your own peril :)

= Lesson 1: weak_ptr is not a pointer =

A weak_ptr is an opaque pointer store/an observer. It is not a pointer: You cannot deref it, and these days you also can't convert it to a raw pointer anymore.

You can ask whether it's expired, but that answer is useless the moment it is given, unless you ask for a conversion to shared_ptr, in which case you get a _real_ pointer back (or nullptr), and _that_ answer remains valid for as long as you hold on to the shared_ptr.

In this is differs from QPointer, which is _also_ observing (resetting itself to nullptr upon deletion of the payload), but is also a pointer: you can deref it, and, since it doesn't really work across threads, it won't be killed under you (though I hasten to add that you just need to grep for "that = this" to find places where it more or less actually is).

So, remember: weak_ptr is not a pointer. QWeakPointer is _not_ QPointer.


= Lesson 2: forget .data() existed =

QWeakPointer::data() is gone. Forget also about QSP::data(): You need it only when you'd also need it on QScopedPointer: when you need to pass the address of the owned object to a raw pointers API. So, almost never.

In particular, use op-> and op*, not .data(). Use the shared_ptr as a pointer, don't run to extract a raw pointer stat and then forget the shared_ptr.


= Lesson 3: if you need to use .data() treat it the same as QByteArray::data() =

That is, don't call it on rvalues unless you pass the result to a function that doesn't store it. In any other case, store the owning object in a named variable and call .data() on _that_. This pins the lifetime of the data to the current scope, and prevents use of dangling pointers.


= Lesson 4: idioms are good =

Handwaving a la "we don't use MT, so we don't need this" etc is ignoring the fact that what I described above a) is idiomatic use of weak_ptr and b) any non-idiomatic use is more complex to reason about.

This is idiomatic use:

   auto x = weak_x.toStrongRef();
   ~~~
   x->~~~
   x->~~~

There's nothing wrong with that code, there's no need for a comment. It's just what you do when you want to access the object hidden in a weak_ptr. If anything, you should add an assertion and explain why you expect x to never be nullptr.

This is non-idiomatic use:

   auto x = weak_x.toStrongRef().data();
   ~~~~
   x->~~~
   x->~~~

That also doesn't need a comment. It needs to be re-written into idiomatic form :)

Thanks for listening,
Marc
_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to