2016-09-09 1:49 GMT+02:00 Thiago Macieira <thiago.macie...@intel.com>: > On quinta-feira, 8 de setembro de 2016 21:08:37 PDT Elvis Stansvik wrote: >> > QESDP doesn't actually require that you derive from QSharedData, >> > only that you have an atomic integer called "ref" in your structure. >> >> I see, that makes sense. And I see now that that's really all that >> QSharedData brings, the ref member. > > Well, it does make the copy constructor private, so that you don't > accidentally copy your shared data outside of the Q(E)SDP, thus accidentally > copying the refcounter when it wasn't 1.
Ah, right. > >> >> In short, I fail to see a strong use case for QESDP compared to using >> >> a QSharedPointer. I'm probably missing something. >> > >> > The fact that it's a smart pointer, not a raw one. >> >> This I don't quite understand. Aren't they both smart pointers? They >> still seem quite similar to me. The difference mainly seems to be the >> slightly different API, and where the refcount is stored >> (external/internal). > > Yes, but I wasn't comparing those two. I was comparing the use of a smart > pointer to not using one. Ah, sorry. Since I was contrasting QSDP and QSharedPointer, I thought you were comparing them. > QESDP has a very limited use-case, as you've > noticed. It's mostly used so you don't need to do the reference counting > manually, like the older Qt classes do (QString, for example). I see. > > I also realise I was probably thinking of the even simpler QScopedPointer > class. > >> >> Does anyone know of a code base that makes liberal use of QESDP, or >> >> could you share how you're making use of it? It's easy to find uses >> >> for the implicit variant (QISDP). >> > >> > qtxmlpatterns, I believe. >> >> Thanks, I'll have a look at that and see how it's put to use there. > > Not very well. In fact, it's an abuse of QESDP, so don't take it as a good > example. I created QSharedPointer *because* qtxmlpatterns was abusing QESDP. Okay, good to know. > >> With the above I was mainly looking for design advise: E.g. like when >> would I choose to use QESDP vs QSDP, and when I would use QSP instead >> of QESDP. I had also heard on IRC that some people preferred to always >> work with QESDP instead of QSDP, thinking the lack of control with >> QSDP was "dangerous", so was looking for opinions on that. > > There are advantages for both QSDP and QESDP. It just depends on how often > your code requires detaching. Take QDateTime as an example (before Qt 5.8). > QSDP allows for easy detaching when necessary and allows you to write code as > if you had a regular, raw pointer: > > This doesn't detach: > bool QDateTime::isValid() const > { > return (d->isValidDateTime()); > } > > This detaches: > void QDateTime::setDate(const QDate &date) > { > d->setDateTime(date, time()); > } > > On the other hand, non-const non-simple functions could make the one serious > mistake of QSDP. There's only one case in QDateTime but it's not obvious, so > here's an example of the mistake from QTextCursor: > > void QTextCursor::setKeepPositionOnInsert(bool b) > { > if (d) > d->keepPositionOnInsert = b; > } > > The "if (d)" function makes a call to QSharedDataPointer::operator T*(), which > detaches. The next line calls QSharedPointer::operator->(), which again tries > to detach, even though we know (by construction) that the reference count is 1 > and there's no need to detach again. The compiler has no way of knowing that, > so it generates code that will never be executed and a comparison whose result > we already know.[1] > > If we used QESDP, instead, we'd control exactly when to detach and, more > importantly, when *not* to attempt to detach. On the other hand, you may make > a mistake and forget to detach somewhere. > > The solution we've found is to make QSDP detach explicitly and then never > again. You can see this in QDateTime (before 5.8) and in QDir: many setter > functions had code like > > QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) > > which causes a detach and then shadows the d variable so that further uses of > d-> now use the raw pointer. > > [1] This is also the most common problem with implicitly-detaching container > classes in Qt. If you have a QString and do str[0] = 'a'; str[1] = 'b';, the > code for detaching is present twice, even though we know by construction that > the second one is not necessary. Thanks a lot for these examples/gotchas! Elvis > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > _______________________________________________ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest