[Interest] Qt::MakePointer for creating QPointer as std::make_shared for creating std::shared_ptr
Mikhail Matrosov
mikhail.matrosov at gmail.com
Fri Oct 17 10:32:21 CEST 2014
On Friday 17 October 2014 09:00:08 Bo Thorsen wrote:
>* Den 17-10-2014 08:42, Reinhardt Behm skrev:
*>* > On Thursday 16 October 2014 01:56:46 Mikhail Matrosov wrote:
*>* >> Hello!
*>* >>
*>* >> In modern C++ there is almost no need to use raw *new* and *delete*. As
*>* >> Bjarne Stroustrup is saying in his “A Tour of C++”: “Avoid ‘‘naked’’ new
*>* >> and delete operations; §4.2.2.”. We use standard containers and smart
*>* >> pointers for that, with std::make_shared and std::make_unique functions
*>* >> for
*>* >> smart pointers creation.
*>* >>
*>* >> In Qt we also have QSharedPointer and QSharedPointer<T>::create(…)
*>* >> method.
*>* >> But we don’t use smart pointers in Qt much, due to parent-driven memory
*>* >> model. And most of QObjects are created with raw *new* operations. Maybe
*>* >> it
*>* >> is a proper thing to add some C++14-style wrapper for creating QObjects
*>* >>
*>* >> like this:
*>* >> 1. namespace Qt <http://qt-project.org/doc/Qt.html
<http://qt-project.org/doc/Qt.html>>
*>* >> 2. {
*>* >> 3. template<class T, class... Args>
*>* >> 4. QPointer <http://qt-project.org/doc/QPointer.html
<http://qt-project.org/doc/QPointer.html>><T>
*>* >> MakePointer(
*>* >> Args&&... args)
*>* >> 5. {
*>* >> 6. T* pObject = new T(std::forward<Args>(args)...);
*>* >> 7. Q_ASSERT(pObject->parent() != nullptr);
*>* >> 8. return pObject;
*>* >> 9. }
*>* >> 10. }
*>* >>
*>* >> Now, one can safely call Qt::MakePointer to create a QObject and be sure
*>* >> it
*>* >> will not leak due to an assertion for an existing parent. And it will
*>* >> free
*>* >> all the calling code from raw *new*operations. One can always use raw
*>* >> *delete* to destroy the object, but he does not have to. And even if he
*>* >> will, it will not lead to dangling pointers problem since QPointer is
*>* >> automatically set to null in this case.
*>* >>
*>* >> I’m planning to use this approach in my code. Do you think it is
*>* >> relevant?
*>* >> Are there any drawbacks?
*>* >>
*>* >> PS This is a cross-post of my question from Qt forums:
*>* >> http://qt-project.org/forums/viewthread/48541,
<http://qt-project.org/forums/viewthread/48541,> where SGaist
*>* >> <http://qt-project.org/mebmer/39728
<http://qt-project.org/mebmer/39728>> suggested me to post here.
*>* >
*>* > This looks to me like a complicated solution to a non existing problem.
*>* >
*>* > Your method will fail for objects that should not have a parent, e.g top
*>* > level windows or objects that are created to be moved to anther thread to
*>* > name just a few.
*>* > In all other cases where you do not want an object to be an orphan (no
*>* > parent) just don't give a default for the usual parent parameter in the
*>* > constructor and check it inside the constructor for parent being
*>* > non-null. This way an ASSERT will give a meaningful message.
*>* >
*>* > In most cases when I need an QObject without parent I create it on the
*>* > stack (no explicit new/delete) because it is just a local variable and
*>* > the compiler take care of creation and destruction.
*>* > Others are created with new and directly have a parent or widgets are
*>* > placed into layouts and get a parent this way.
*>* >
*>* > Just because Bjarne Stroustrup has said it, does not mean it make sense in
*>* > this context and has to be blindly followed even if it make code more
*>* > complex. He also said to write _clear_code_. And this takes precedence,
*>* > at least for me.
*> >* I have had this discussion with countless customers. I almost never use
*>* smart pointers, except to do exception safety. And that's only with a
*>* QScopedPointer.
*> >* Using a shared pointer is to me a violation of a couple of my most
*>* fundamental coding rules: Ownership and responsibility. I usually know
*>* exactly what object owns and controls other objects. So when the owner
*>* think it's time to delete the object, the object will be deleted. Using
*>* a shared pointer would mean the object lives on to some unknown time.
*> >* QPointer is essentially a weak pointer, but one that doesn't rely on a
*>* shared pointer. I use that a lot.
*> >* There are cases where an object has it's own life and in those cases it
*>* is a possibility that shared pointers are valid. Network code in boosts
*>* ASIO (which is IMHO completely overengineered, so this might be a bad
*>* example) is one case.
*> >* The *only* argument I have ever heard for shared pointers that have some
*>* validity is that companies do not have senior C++ experts only. In the
*>* real world, they employ junior people or people coming from Java or C#.
*>* Giving them shared_pointers is a way to take away a lot of the cases
*>* where you shoot yourself in the foot.
*> >* The counter argument is that they never learn The Right Way if you don't
*>* just throw them in and see if they swim. Then they can return to Java :D
*> >* I disagree with Reinhardt that it's a non-existing problem. But I also
*>* disagree with Stroustrup that shared pointers are the solution to it.
*>* Education in OO and C++ is IMHO the proper solution.
*> >* Bo.*
Bo, you've said a lot about smart pointers, but I didn't get your thought
on the proposed solution. Except you are using QPointer a lot (I suggest
you are not calling it smart pointer, right?).
What do you think of the Qt::MakePointer function, or maybe you have any
ideas on how it should look or maybe on some different but related
approach? Since you agree that problem exists.
-----
Best regards, Mikhail Matrosov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141017/2e2c96eb/attachment.html>
More information about the Interest
mailing list