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?


  • Qt Champions 2016

    @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 use QScopedPointer in your QObject 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 the QSharedDataPointer 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.


  • Qt Champions 2016

    @QLab
    Sure, because you're creating a new DataPrivate object and attaching it to the QScopedPointer 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?


  • Qt Champions 2016

    @QLab
    Code is correct from C++ point of view. The thing is QScopedPointer 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 the QSharedDataPointer or QExplicitlySharedDataPointer class coupled with your private object subclassing QSharedData. It will have better performance indeed, since QSharedData 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,


  • Qt Champions 2016

    @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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.