[Development] parented_ptr

Volker Hilsheimer volker.hilsheimer at qt.io
Tue Oct 28 22:15:55 CET 2025



> On 23 Oct 2025, at 09:56, Ville Voutilainen <ville.voutilainen at gmail.com> wrote:
> 
> On Thu, 16 Oct 2025 at 17:32, André Somers via Development
> <development at qt-project.org> wrote:
>>>> Perhaps it might be easier or better to add a make_child template method
>>> to QObject that returns a new instance of the template type, parented to
>>> the object you call it on?
>>> 
>>> That's actually the solution I was looking for.
>>> I love that idea. Thank you.
>>> 
>>> What type is the returned pointer? I like to have one that has the
>>> semantical guarantee of being a child object. This is beneficial to
>>> distinguish classic owned pointer member variables from borrowed from
>>> the Qt Object tree.
>>> 
>>> Do you have an idea?
>> Well, my suggestion would be to not introduce a separate non-owning
>> pointer type at all, so it would just return the type itself, just like
>> new does.
> 
> Precisely so. Our ostensible declaration (and definition) is
> 
> class QObject {
> ...
> public:
>  template <class Child, class... Args>
>  Child* makeChildObject(Args&&... args)
>  {
>     return new Child(std::forward<Args>(args)..., this);
>  }
> };
> 
> and that's all there is to it.
> 
> The reason it's a reach too far to return some
> semantically-parented-pointer instead is adoptability.
> With this approach, you can just change
> 
> MyType* var = new MyType(foo, bar, someParent);
> 
> to
> 
> MyType* var = someParent->makeChildObject<MyType>(foo, bar);
> 
> and there's no need for heavier refactorings in how that code uses
> MyType*. It doesn't need to be refactored to
> use a parented_ptr everywhere.


The above pattern seems to me to be the most pragmatic approach for an API addition to Qt. Perhaps also a QObject::addChild(std::unique_ptr<QObject *> child) which moves the ownership of the pointer held by child into the callee.


I do see that a parented_ptr<> type makes the intent clear to readers, static analysers, AI tools etc, in the same way that std::move’ing a std::unique_ptr would. And that type then producing clear failures (compile time if possible, although in practice it will have to be runtime assertions) in case of incorrect usage might be practical. But that can be achieved via explicit declaration of the variable, e.g.

parented_ptr<QLineEdit> input = dialog->makeChildWidget<QLineEdit>();
// would assert in ~parented_ptr if ‘input’ doesn’t have a parent


This makes the intent clear, while still allowing

QLineEdit *input = dialog->makeChildWidget<QLineEdit>();


Volker



More information about the Development mailing list