[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Re: Initialization of QSharedDataPointer's for empty objects (i.e. Foo::Foo(void))
From: Thiago Macieira <thiago () kde ! org>
Date: 2013-04-29 22:16:29
Message-ID: 1647832.4WUlSLJ3Nl () tjmaciei-mobl2
[Download RAW message or body]
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<QNetworkProxyPrivate>::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
["signature.asc" (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic