[Development] unique_ptr and Qt, Take 2
"Lutor, Zoltán"
zoltan.lutor at gmail.com
Fri May 3 20:24:57 CEST 2019
+1 from my side.
Explicit ownership declaration is the king. always - all other solutions are paid with sweat and blood. but mainly with blood... ;)
Zoltan
On Friday, May 3, 2019, Daniel Teske wrote:
> 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
>
>
More information about the Development
mailing list