Solved QSharedDataPointer instead of QScopedPointer
-
Hi,
In my company I write library using Qt and I use PIMPL idiom with QScopedPointer to private class.
Now I see that I can use QSharedData and QSharedDataPointer instead of QScopedPointer to get better perfomance and avoid copy in same cases, for example when I return my 'data' class by value.
So I should always use QSharedData / QSharedDataPointer instead of QScopedPointer? I know that only in one case it can not be done - when my class inherit from QObject. But what in other cases?
-
@QLab
Hello,
They are quite different.QScopedPointer
only ensures your object will be deleted at the end, but does not allow for copying.QSharedDataPointer
/QExplicitlySharedDataPointer
on the other hand are made exactly to facilitate that. You can useQScopedPointer
in yourQObject
subclasses to ensure your private object will be deleted automatically when the public object is destroyed. If in fact you intent to provide a shared data class (like Qt's containers and images) then your best bet is to use theQSharedDataPointer
and the like.Kind regards.
-
@kshegunov said:
They are quite different. QScopedPointer only ensures your object will be deleted at the end, but does not allow for copying.
Oh, now i use QScopedPointer for my PIMPL and my class allows to be copied, copy ctor:
Data::Data(const Data &other)
: d(new DataPrivate(*other.d.data()))
{
}and it works fine.
-
@QLab
Sure, because you're creating a newDataPrivate
object and attaching it to theQScopedPointer
instance. This, if memory serves me, should give you a compile error:Data::Data(const Data &other) : d(other.d) // You copy the QScopedPointer intance here { }
Kind regards.
-
Yes, this causes error because code is wrong. You need create new DataPrivate class by 'new' - It is pointer. Especially inside copy constructor.
So we can say that if my class do not inherit from QObject my private 'data' classes should inherit from QSharedData for better performance?
-
@QLab
Code is correct from C++ point of view. The thing isQScopedPointer
does not provide a copy constructor for a reason, and that is exactly because it doesn't have a reference counter, so if you copy the pointer you'll run into a double delete predicament. If you're copying your objects like you've shown in your example, it's a good bet that you're better off using either theQSharedDataPointer
orQExplicitlySharedDataPointer
class coupled with your private object subclassingQSharedData
. It will have better performance indeed, sinceQSharedData
includes an internal reference counter and you make shallow copies instead of full data copying (like you're currently doing).Kind regards.
-
So conclusion: QScopedPointer for classes which are noncopyable otherwise QSharedData / QSharedDataPointer.
Thanks,
-
@QLab
Hello,
Yes, unless you have some very specific use cases, use implicit/explicit sharing techniques instead of scoped pointer to benefit the most from your data classes.Kind regards.