[Development] unique_ptr and Qt, Take 2

Matthew Woehlke mwoehlke.floss at gmail.com
Thu Jun 13 21:51:21 CEST 2019


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.

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

With that out of the way, and having gone back and looked more closely
at your original post...

> To reiterate a point that seems to be a source of misunderstanding,
> in the design I proposed the vast majority of objects are never owned
> by a unique_ptr. Most objects are created with a parent.
> 
> 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.)

Mostly what I don't want to see (and I'll freely admit this is probably
a result of others' fixation) is suddenly having to litter my Qt code
with `std::make_unique` and `std::move` all over the place for no more
lifetime safety than I've always had.

> So, I think what I have actually proposed has zero costs to those that
> don't want to use it, while enabling those that e.g. want to make use of
> tooling around memory managment capable of doing so.

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?)

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.

-- 
Matthew


More information about the Development mailing list