Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Adding to RobbiE's answer, the <a href="http://qt-project.org/doc/qt-5.0/qtcore/qpointer.html" rel="nofollow noreferrer">QPointer</a> and <a href="http://qt-project.org/doc/qt-5.0/qtcore/qsharedpointer.html" rel="nofollow noreferrer">QSharedPointer</a> are two complemetary classes that serve different functions. </p> <h2>QPointer and its Caveats</h2> <p>A <code>QPointer</code> is a weak pointer to a <code>QObject</code>. It resets itself to zero when the pointed-to object is destroyed. It is not an owning pointer: it never deletes the object itself, and it doesn't guarantee the object's existence. Use it to avoid having a dangling pointer to an object whose ownership is managed elsewhere. Check whether the pointer is null before each use. You will run into race conditions if the object is destructed in another thread:</p> <pre><code>if (pointer) /* another thread can destruct it here */ pointer-&gt;method(); </code></pre> <p>The <code>QPointer</code> itself is thread-safe, but the code that uses it cannot ever be thread-safe due to the insufficient API provided by <code>QPointer</code>.</p> <p>The <code>QPointer</code> is always safe to use from the main thread with widget objects, and with the objects owned by widget objects where the parent-child relationship is established. The objects and their users are in the same thread, so the object will not be disposed by another thread between the pointer null check and the use of the pointer:</p> <pre><code>QPointer&lt;QLabel&gt; label(...); if (label) label-&gt;setText("I'm alive!"); </code></pre> <p>You need to be careful if you're reentering the event loop. Suppose we have:</p> <pre><code>QPointer&lt;QLabel&gt; label(...); ... if (label) { label-&gt;setText(...) QFileDialog::getOpenFileName(...); // Here the event loop is reentered, and essentially any other code in your // application can run, including code that could destruct the widget that // you're using. The `deleteLater` calls won't do it, since they defer to // the main event loop, but it's not always obvious that nothing else // will. The line below can thus dereference a null pointer (IOW: crash). label-&gt;setText(...); } </code></pre> <p>At the very least, you need to re-check the <code>QPointer</code> every time after you invoke principally unrelated code - e.g. emit a signal (anyone can do anything in reaction to it!), return an event-loop-reentering call like <code>exec</code>. etc. That's also why blocking calls are evil: you should never use them.</p> <pre><code>QPointer&lt;QWidget&gt; widget(...); ... if (label) { label-&gt;setText(...); QFileDialog::getOpenFileName(...); // Reenters the event loop, the widget may get deleted. } // Not re-checking the pointer here would be a bug. if (label) { label-&gt;setText(...); ... } </code></pre> <h2>QSharedPointer and QWeakPointer</h2> <p><em>This section is left as a reference. In modern code, you should be using <code>std::shared_ptr</code> and <code>std::weak_ptr</code>, without any reservations. They have been in C++ for 7 years as of 2018.</em></p> <p>A <code>QSharedPointer</code> is an owning pointer. It works like variables in Java and CPython, or like <code>std::shared_ptr</code>. As long as there is at least one <code>QSharedPointer</code> pointing to an object, the object is kept around. When the last <code>QSharedPointer</code> is destructed, the object gets destructed and deleted.</p> <p>The <code>QWeakPointer</code> is <code>QSharedPointer</code>'s cousin. It is non-owning. It tracks whether the objects held by <code>QSharedPointer</code>s are still alive. It resets itself to <code>nullptr</code> when the last <code>QSharedPointer</code> that owns the object goes away. It can be thought of as a generalization of <code>QPointer</code> to non-<code>QObject</code> classes. The only safe way to use a <code>QWeakPointer</code> is to convert it to a <code>QSharedPointer</code>. When you hold a shared pointer, the object will be guaranteed to stay alive.</p> <p>A <code>QPointer</code> is like a <code>QWeakPointer</code> for <code>QObject</code>s, but it doesn't require the existence of a <code>QSharedPointer</code>.</p> <p>It is an error to use a <code>QSharedPointer</code> on an object that's not allocated on the heap, and on an object whose lifetime is managed by other mechanisms. For example, it's an error to have a <code>QSharedPointer</code> to a <code>QObject</code> that has a parent. The object's parent would delete it, and you would end up with a dangling <code>QSharedPointer</code>! Qt has some built-in checks that issue warnings when that happens, but by that time it's too late and undefined behavior has struck.</p> <h2>QScopedPointer</h2> <p><em>This section is left as a reference. You should be using <code>std::unique_ptr</code>, without any reservations. It has been in C++ for 7 years as of 2018.</em></p> <p><code>QScopedPointer</code>, just like <code>std::unique_ptr</code>, is a solely owning pointer. Its job is to delete the held object when it goes out of scope. The C++11 <code>unique_ptr</code>'s name is very apt: it <em>is</em> a unique pointer, in the sense that it's an error to try and copy such pointers. There is always only one <code>QScopedPointer</code> that owns a given object, and it does not cooperate with other smart pointer types. You can fetch a raw pointer to underlying object by calling the <code>data</code> method.</p> <h2>std::auto_ptr</h2> <p>This pointer was an attempt at working around lack of move semantics in C++98/03. Due to its broken copy semantics, the use of this class should be treated as a bug. Use <code>std::unique_ptr</code> or <code>std::shared_ptr</code> - the former if it suffices that it be movable, the latter if several copies of it must coexist.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload