Hi Daniel, if I understand your proposal right it can dangle and is an alias to 
raw pointer?

In this thread you speak much about the implementation but not so much what use 
cases it fixes and which it is not.

One problem with the life time by parent management is the deletion in the base 
QObect destructor. That leads to calls to half destructed objects with UB 
behavior.

I don't see how your proposal is fixing that. Should we even encourage 
ownership by parent? I see the value for Q widgets but what about other use 
cases.


________________________________
From: Development <[email protected]> on behalf of Daniel 
Schürmann <[email protected]>
Sent: Friday, October 31, 2025 15:28
To: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: [Development] parented_ptr


Hi,

On 30-10-2025 18:20, Daniel Schürmann wrote:
> Hi Marc and others
>
> > Just never create a child QObject w/o the final parent, and
> everything will be peachy.
>
> This is one of the drivers for initiative we can enforce with
> “makeChildObject()” and no  longer encouraged “new Object(this)”.
> > Every function that transfers ownership as a raw pointer is worth
> being replaced by one taking/returning by unique_ptr. Let the API
> enforce ownership transfer instead of letting the reader of the code
> guess.
>
> I agree. So we should encourage to use
> pParent->addChild(std::move(pChild)) instead of pChild->setParent(pParent)
>
> > I wouldn't even assert in the destructor. That will fire already
> when these things are held as member functions in the "wrong" order.
>
> I am as well against an ASSERT that may crashes the productive build
> for a semantical reason. What is the best pattern for Qt?
> How about issue a qWarning during the QParentedPointer *constructor*
> like we have in QObject::~QObject()? I have good experience with this.
>
> So, let me summarize the latest discussion, to verify if I got it right:
>
> We will introduce:
... in separate contributions...
>
> 1: Child* QObject::makeChildObject()
>
> with some template magic to automatically set the parent pointer and a
> static_assert for pParent == this otherwise
You would not need much magic, but sure. I can see a use case for this one.
>
> 2: QParentedPointer<Child>
>
> with a non-fatal warning or similar if the parent is null. Disallow
> copy and move, because for the borrowing case we want to use raw
> pointer or QPointer in line with the C++ core guideline.

Wait... Disallow copy and move? I don't get what the point is then. You
say for the "borrowing case" we want raw pointers (fair enough), but
QParentedPointer itself already _is_ borrowed by definition, no? It is
conceptually owned by the parent the pointer is explicitly advertising
is set. What's the point of this thing if it's not copyable? It would
make their use very limited indeed, perhaps just used as private members
of a class containing some sub items or as temporary variables in a
function that sets up a dialog or something those lines.

Could you explain more clearly why this thing cannot be copyable or movable?

> 3: QObject::addChild(std::unique_ptr<QObject *> child)
...

Cheers,

André

Hi André That's out of the dilemma that we want both a machine readable 
notation for parented pointers and following the C++ core guideline. I have no 
strong opinion here, I just want to give an advice how the QParentedPointer is 
meant to use (like I have used it in the past) What is clear for me is the 
normal borrowing case: void Other::doSomethingWithThePointer(QObject* pObject); 
// does not not store And the weak reference case: void 
Other::setPointerForLater(QPointer<QObject*> pObject); // allow to store, use 
after null check What I have read in this thread is that we don't want to 
change this recommendation and see QParentedPointer everywhere. But where to 
borrow from? We don't have access to the original owned pointer inside the 
QObject. We can use QObject::children() to borrow all at once. Or as the usual 
practice make a second copy of the pointer in the inherited Object where we can 
"borrow" the already borrowed child pointer (Not recommended by the C++ Core 
Guidelines). Here comes the super-power of QParentedPointer in. class 
Parent::QObject { ... QParentedPointer<Child> m_child; // <- It is allowed to 
store without QPointer, because its a reference to the pointer we own anyway. 
Child* m_child; // this is ambiguous, because it can be a legacy owned object 
or a not allowed storage of a borrowed pointer. (don't use) } .. m_child = 
makeChildObject<Child>(); .. m_other->doSomethingWithThePointer(m_child);

Conclusion, we have no use case for copy a second QParentedPointer<Child> from 
m_child or move m_child out of Parent
.

Does that make sense?

Best regards,

Daniel







-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to