From kde-core-devel Mon Apr 29 22:16:29 2013 From: Thiago Macieira Date: Mon, 29 Apr 2013 22:16:29 +0000 To: kde-core-devel Subject: Re: Initialization of QSharedDataPointer's for empty objects (i.e. Foo::Foo(void)) Message-Id: <1647832.4WUlSLJ3Nl () tjmaciei-mobl2> X-MARC-Message: https://marc.info/?l=kde-core-devel&m=136727382520250 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--nextPart2502548.c8ExvUV4jW" --nextPart2502548.c8ExvUV4jW Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" On segunda-feira, 29 de abril de 2013 21.52.37, Milian Wolff wrote: > I.e.: In the ctors that construct an "empty" object do not call "new > Private" but instead (re-)use a static shared empty object created on the > stack - see shared_empty and shared_null in qstring.{cpp,h}. You probably did not mean what you said: you do not want something allocated on the stack. You want a global. Like QString :-) To be *really* like QString, you want your private to be POD. That means you cannot derive from QSharedData, you cannot use QAtomicInt, QString or QByteArray. That may be taking it a bit too far. If your private class is not POD, you should use a K/Q_GLOBAL_STATIC instead to hold your private. Examples: corelib/mimetypes/qmimedatabase.cpp:Q_GLOBAL_STATIC(QMimeDatabasePrivate, staticQMimeDatabase) corelib/tools/qlocale_win.cpp:Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate) gui/text/qfontdatabase.cpp:Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb) network/access/qabstractnetworkcache.cpp:Q_GLOBAL_STATIC(QNetworkCacheMetaDataPrivate, metadata_shared_invalid) plugins/bearer/qnetworksession_impl.cpp:Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager); sql/kernel/qsqlquery.cpp:Q_GLOBAL_STATIC_WITH_ARGS(QSqlQueryPrivate, nullQueryPrivate, (0)) > I do wonder though why QString has both, a shared_empty and a shared_null > object. A single one should suffice for most objects, no? QString().isNull() == true QString("").isNull() == false > Does anyone have any experience with this? Are there any pitfalls or > downsides to the approach taken by QString? I also thought about not > initializing the QSaredDataPointer at all but that would require a lot of > additional code when its being used to ensure its only accessed when it is > initialized. I think the pattern applied in QString is much nicer in that > regard. It is, but the pattern of having a null d pointer also exists elsewhere in Qt. For example, in QUrl, it's implemented manually. But there are also a few examples of doing that with QSharedDataPointer. Take a look at QNetworkProxy or QUrlQuery: template<> void QSharedDataPointer::detach() { if (d && d->ref.load() == 1) return; QNetworkProxyPrivate *x = (d ? new QNetworkProxyPrivate(*d) : new QNetworkProxyPrivate); x->ref.ref(); if (d && !d->ref.deref()) delete d; d = x; } And then: QNetworkProxy::ProxyType QNetworkProxy::type() const { return d ? d->type : DefaultProxy; } -- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Software Architect - Intel Open Source Technology Center PGP/GPG: 0x6EF45358; fingerprint: E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358 --nextPart2502548.c8ExvUV4jW Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iD8DBQBRfvFLM/XwBW70U1gRAvHzAJ96B6gbDrnevYUsjr9hJmPCNeF7NACcDyMu by1GVNA9ur0EDZYWVpE40W0= =xtDn -----END PGP SIGNATURE----- --nextPart2502548.c8ExvUV4jW--