[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 15:10:32 CEST 2014


Ok, I got your point. Thanks to all for the feedback!


-----
Best regards, Mikhail Matrosov

2014-10-17 12:34 GMT+04:00 Bo Thorsen <bo at vikingsoft.eu>:

> Den 17-10-2014 10:32, Mikhail Matrosov skrev:
>
>> 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>
>> />/  >>     2. {
>> />/  >>     3.   template<class T, class... Args>
>> />/  >>     4.   QPointer <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,  where SGaist
>> />/  >> <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.
>>
>
> I just use new and delete, and I won't change that. If others want to add
> syntactic sugar, I don't care about it. As long as it's not in my code :)
>
> Bo.
>
> --
> Viking Software
> Qt and C++ developers for hire
> http://www.vikingsoft.eu
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141017/3f0ed5c8/attachment.html>


More information about the Interest mailing list