[Development] unique_ptr and Qt, Take 2
Daniel Teske
qt at squorn.de
Sat May 4 09:03:26 CEST 2019
Иван Комиссаров:
> IMHO, it should be a Qt6 feature. It’s awesome.
>
> However, I liked the idea (is it deprecated or what?) of a template
> method
> template<typename T, typename Args…>
> std::observer_ptr<QObject>
> qMakeChild(gsll::not_null<std::observer_ptr<QObject>> parent, Args… args)
> {
> return parent->adoptChild(std::make_unique<T>(args));
> }
For some classes, notably QLayout constructing with a parent is
different from setting a parent later. The former automatically sets the
layout, whereas the later doesn't.
So, what you would need to do is in pseudo code:
std::observer_ptr<QObject>
qMakeChild(gsll::not_null<std::observer_ptr<QObject>> parent, Args… args)
{
auto obj = std::make_unique<T>(args);
if hasMember(T:initWithParent)
obj->initWithParent(parent)
return parent->adoptChild(std::move(obj));
}
And obviously create a initWithParent method on all classes that are
special like QLayout. I didn't explore that, as it didn't feel that nice
to me
>
> Maybe I’m asking too much, but it would be nice get rid of raw
> pointers completely switching to pair std::unique_ptr/std::observer_ptr
>
I don't think observer_ptr has only miniscule benefit over a raw pointer
and I think it's ugly.
Thiago Macieira:
> On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
>> std::unique_ptr<QPushButton> rightButton =
>> std::make_unique<QPushButton>("RIGHT");
>> layout->addWidget(std::move(rightButton));
> The problem in this particular example is that once you've added the
> widget,
> the rightButton smart pointer no longer has a pointer. You can't
> continue to
> set up your push button. In most cases, this is just a matter of
> moving the
> set up before the addition / reparenting, or using the other idiom
> where the
> object is never in a smart pointer in the first place.
>
> So this begs the question of whether std::unique_ptr is the best smart
> pointer
> for this scenario. Would it make sense to create one that understands
> parent-
> child relationship?
addWidget could return a raw pointer to he widget, also that would
require making addWidget and a bunch of other functions templates.
(They need to be templates, because we want to return the subclass that
is stored in the unique_ptr, that is: T * addWidget(std::unique_ptr<T>)
is the right signature.)
But, on the topic of using our own smart pointer class.
I think unique_ptr actually works well enough with Qt's parent/child
relationship with the right apis, because both use similar enough concepts.
Using the standards mechanism for memory management has the benefit that
it is well-known outside the Qt world and aligns Qt better with modern
practices, whereas our own smart pointer is again our own very different
corner of C++.
I think that standard C++ is developing quite rapidly and for Qt's to
profit from that development it needs to try harder to adopt changes in
C++. And I believe that to be critical to Qt's long term success.
> std::unique_ptr<QPushButton> rightButton =
> std::make_unique<QPushButton>("RIGHT");
> layout->addWidget(std::move(rightButton));
> To really, really, really nitpick, this last line is (or feels) wrong:
> layouts do not take ownership of the widgets they manage. An ownership
> transfer MAY happen immediately (if the layout is installed) or later
> (as soon as the layout is installed).
I actually didn't know that and must have missed it. ( There are
obviously lots of apis, I did check the documentation and read the
implementation of most functions, but it's rather likely that a bunch of
my implementations miss subtle details.)
So, what the function should do is to always do take ownership and if
that requires behaving a bit differently than addWidget, so be it.
For example one case where I did catch something like that, the two
variants of QAbstractItemView::setIndexWidgetbehave slightly differently.
* If the model index is valid, both take ownership of the widget.
* If the model index is invalid
* The normal version does nothing
* The unique_ptr version deletes the widget
Now, I'm in a bit of a hurry atm, but QLayout basically would need to
ensure that any unique_ptrs that it took ownership of are either passed
on to its parent widget, or are deleted in ~QLayout.
daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20190504/0a743cad/attachment.html>
More information about the Development
mailing list