[Development] unique_ptr and Qt, Take 2
Daniel Teske
qt at squorn.de
Fri May 3 19:22:20 CEST 2019
Hi,
a year back I wrote a patch that added unique_ptr apis to most of
qtbase. I still think that would be a good addition to Qt, and thus I've
updated the patch with the feedback gained at the Contributor Summit
last year and taking into account that with Qt6, binary compatibility is
not required. The result is: https://codereview.qt-project.org/#/c/260618/
Since not everyone remembers last years mail, I'll explain the problem
that patch is trying to solve, but won't go into all the details:
Consider this small program:
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
QPushButton *leftButton = new QPushButton("LEFT", &widget); // Owned by
widget
layout->addWidget(leftButton); // No Ownership transfer
QPushButton* rightButton = new QPushButton("RIGHT"); // No owner
layout->addWidget(rightButton); // Ownership transfer
QObject::connect(leftButton, &QPushButton::clicked,
[leftButton]{
QMenu menu;
auto act = new QAction("Action!"); // No Owner
menu.addAction(act); // No Ownership transfer
menu.exec(leftButton->mapToGlobal(leftButton->rect().bottomLeft()));
});
widget.show();
In that program:
* The left button is owned at construction by the parent.
* The right button is created unowned, but adding a widget to a layout
automatically sets the parent
* The action is created unowned, and is leaked because addAction does
not set the parent.
That is, even though:
* layout->addWidget(new QPushButton()) and
* menu->addAction(new QAction())
look very similar, the later leaks memory.
That's a less than ideal api. With Qt6 there's a opportunity to leverage
unique_ptr to ensure that memory is not leaked.
The patch adds two ways to create new QObjects:
* std::make_unique<QPushButton>("LEFT"); and
* parent->makeChild<QPushButton>("RIGHT");
* adds various overloads for ownership transfer
The first half of the program would thus look like:
QWidget widget;
QHBoxLayout *layout = widget.makeChild<QHBoxLayout>();
QPushButton *leftButton = widget.makeChild<QPushButton>("LEFT");
layout->addWidget(leftButton);
std::unique_ptr<QPushButton> rightButton =
std::make_unique<QPushButton>("RIGHT");
layout->addWidget(std::move(rightButton));
For second half, the naive transformation:
{
QMenu menu;
auto act = std::make_unique<QAction>("Action!");
menu.addAction(act.get());
menu.exec(leftButton->mapToGlobal(leftButton->rect().bottomLeft()));
}
does no longer leak memory, instead the action is freed at the end of
the scope as its still owned by the unique_ptr.
I believe that Qt6 is a unique opportunity to add apis for better memory
management to Qt.
So, who thinks that this is something that ought to be a Qt6 feature?
And who wants to actually help make that happen?
daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20190503/99e19965/attachment.html>
More information about the Development
mailing list