[Development] The future of smart pointers in Qt API

Volker Hilsheimer volker.hilsheimer at qt.io
Tue Feb 4 17:47:57 CET 2020


> On 4 Feb 2020, at 16:12, Ville Voutilainen <ville.voutilainen at gmail.com> wrote:
> 
> On Tue, 4 Feb 2020 at 15:40, Volker Hilsheimer <volker.hilsheimer at qt.io> wrote:
>>>> This works, but now you are encoding the visual hierarchy of the widgets in two places: when asking the presumed parent to create the widgets; and when setting up the layout, which might do things differently (esp once you start refactoring complex UIs).#
>>> 
>>> That's not a problem. The code simply behaves as if you would have used the current constructors that take a parent parameter.
>>> 
>>> Ownership transfers between different qt parents don't violate the invariant. And they continue to work just like before.
>> 
>> 
>> So how is the above usage of makeChild an improvement over calling operator new to instantiate your objects?
> 
> The result of makeChild never leaks.


True that.


>>> But that just means that QBoxLayout::addWidget(std::unique_ptr<>) has to behave imho saner in that edge case and actually delete the widgets that were added but never parented. (And I should really implement that to show how it would work.)
>> 
>> 
>> That seems like a terrible idea. One of the layout’s jobs is to set up the parent/child hierarchy so that you as a developer don’t have to.
> 
> I don't see how that idea changes that.


Iif the layout deletes widgets that were created without parent, instead of adding it to the correct parent, then that’s a change. You have to create widgets with parents, and add them to the layout (which might then add it to another parent, which at the very least introduces unnecessary overhead of ChildAdded/Removed event processing).


>> Do we really want to make it harder for people to write UIs just because the resulting code doesn’t satisfy a C++ idiom?
> 
> It's not a question of satisfying idioms for the sake of satisfying
> idioms, it's a question of avoiding bugs that we know
> based on decades of experience to be difficult to avoid with raw pointers.


That’s my point:

I do not believe that the decades of experience we have with QObject’s parent/child model support the claim that it is inferior to using smart-pointers. It’s not something people constantly struggle with.

That doesn’t invalidate the suggestion that we should use smart pointers in Qt code, or in Qt APIs where we are not benefitting from QObject trees.


>> If you don’t care about the things that QObject/QWidget does for you, then don’t use QObject/QWidget. And if you do use QObject/QWidget and get a consistent object model from it, then I’m really not convinced that adding smart pointers to the API is making the code clearer, or in any way more explicit. It’s not like the ability of using std::unique_ptr means that people no longer have to be familiar with Qt’s basic concepts to use it correctly.
> 
> Correct, but if code moves a std::unique_ptr into a function call
> argument, I know that ownership is transferred, by just glancing at
> the code. With a raw pointer, I don't know that.


But ownership isn’t transferred if you call QLayout::addWidget; it is never transferred to the layout object - it might be transferred to the QWidget that the layout operates on.

So you read that one line of code and make the wrong assumption. If you delete the layout object before you set it on the parent widget, then you end up with leaks, unless we make the change above where QLayout assumes ownership.

If you understand Qt (and don’t assume that by understanding some basic C++ concepts you can use any framework), then you see that widgets are added to a layout that is used, and are therefore managed objects.


Volker




More information about the Development mailing list