[Development] unique_ptr and Qt, Take 2

Ville Voutilainen ville.voutilainen at gmail.com
Thu Jun 13 22:09:16 CEST 2019


On Thu, 13 Jun 2019 at 22:54, Matthew Woehlke <mwoehlke.floss at gmail.com> wrote:
>
> On 13/06/2019 14.13, Daniel Teske wrote:
> > On June 12, 2019 23:13:14 Matthew Woehlke wrote:>> Generally, if you follow three rules:>>>> - If you create an object
> on the stack, either don't parent it or ensure>>   its parent outlives
> it. (Usually not hard!)>> - If you create an object with `new`,
> **create** it with a parent.>> - Otherwise use a smart pointer
> (QScopedPointer or QSharedPointer)ยน.>>>> ...you just won't have
> problems.> > And that doesn't need to change with my design at all.
> To be fair, I was responding more to Giuseppe and had only briefly
> looked at the original mail. In particular, I was responding to the part
> where he quotes your example:
>
> >>>>>      QMenu menu;
> >>>>>      auto act = std::make_unique<QAction>("Action!");
> >>>>>      menu.addAction(act.get());
>
> IMHO that code should never exist, and should not be encouraged. Leaving
> aside that one could use QMenu::addAction(QString) here, even in other
> cases similar to this where that would not apply, I would encourage
> following one of my first two rules instead.

The minor problem being that to not so small audiences,
new Whoosh(something);
just looks like a bug, and then you need to look three times to
realize that something is a parent.

>
> That's one of the things I love about Qt; object hierarchies give me
> working dynamic memory management without needing even smart pointers.

That's the one thing that makes me queasy about using Qt in large
applications; I always need
to worry about ownership relationships, because I can't program with
smart pointers. I had the pleasure
of writing smart-pointer-only code 20 years ago; it was quite
pleasant, especially considering that
the largeish application was leaking like a sieve and doing
use-after-free in all too many places.
Once we plugged boost's smart pointers into it, all those problems
went away over a weekend,
and we never looked back.

> > And there are small benefits that even those that don't want to use
> > unique_ptr, can get with minimal effort. For example by using the new
> > makeChild function:
> >
> > parent->makeChild(...);
>
> ...this actually seems pretty reasonable to me, especially as it only
> needs to touch the API for 1-2 classes (QObject, maybe QWidget). You're
> just providing an alternate way of following my second rule, which is
> arguably better, especially by modern C++ standards, as a) it never uses
> a bare `new`, and b) it works with QObject subclasses that have bad
> ctors that don't take a parent. (I admit I've written a few, though
> usually that is because the particular class is not expected to be heap
> allocated, or is expected to be lifetime-managed in some other manner.)

This would indeed be a great improvement, regardless of what we do
with smart pointers.

> My "concern", and possibly why everyone fixated on the unique_ptr stuff,
> is how wide-sweeping the necessary API changes will be. Modifying every
> method, everywhere, that reparents a QObject is a little intimidating.
> (Maybe you have some WIP that can put this into perspective?)

Like https://codereview.qt-project.org/c/qt/qtbase/+/260618 ?

> Adding (templated) QObject::createChild is much more approachable (and
> also conveniently dodges having anything to do with STL, which can be a
> hot-button issue on its own). I suspect if you were to pursue that
> separately, it would have a good chance of being accepted, and with many
> fewer passions inflamed in the process.

+1.


More information about the Development mailing list