9

I have a situation where a QSharedPointer managed object signalizes that it has finished it's purpose and is ready for deletion soon (after execution left the function emitting my readyForDeletion signal). When working with normal pointers, I'd just call QObject::deleteLater on the object, however this isn't possible with a QSharedPointer-managed instance. My workaround is the following:

template<typename T>
class QSharedPointerContainer : public QObject
{
   QSharedPointer<T> m_pSharedObj;

public:

   QSharedPointerContainer(QSharedPointer<T> pSharedObj)
      : m_pSharedObj(pSharedObj)
   {} // ==> ctor

}; // ==> QSharedPointerContainer

template<typename T>
void deleteSharedPointerLater(QSharedPointer<T> pSharedObj)
{
   (new QSharedPointerContainer<T>(pSharedObj))->deleteLater();
} // ==> deleteSharedPointerLater

This works well, however there's a lot of overhead using this method (allocating a new QObject and so on). Is there any better solution to handle such situations?

demonplus
  • 5,036
  • 11
  • 41
  • 56
athre0z
  • 422
  • 4
  • 11
  • 4
    So you have an object that is managed by shared ownership (there are several objects that claim ownership) yet at the same time it manages its own lifetime (by having a readyForDeletion signal)? Sounds to me like you've got a really messed up ownership situation. Instead of looking for workarounds, try to clear up who is really responsible for the object and therefore who should delete it. – Sebastian Redl Sep 27 '12 at 14:38
  • I have to agree with @Sabastian. I was about to post a similar comment when his came in. If your object keeps track of when it is safe to be deleted, just use a plain old pointer, and handle the `readyForDeletion` signal on whatever class creates the object in the first place. – Dave Mateer Sep 27 '12 at 14:40
  • Thank you for your comments. In my actual program things are a lot more complicated, however, taking a look at the abstract problem, it becomes clear that using a QSharedPointer in this context is no good idea at all. – athre0z Sep 27 '12 at 14:48

2 Answers2

21

You can use the QSharedPointer constructor with the Deleter :

The deleter parameter specifies the custom deleter for this object. The custom deleter is called, instead of the operator delete(), when the strong reference count drops to 0. This is useful, for instance, for calling deleteLater() on a QObject instead:

 QSharedPointer<MyObject> obj =
         QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);
BaCaRoZzo
  • 7,022
  • 6
  • 44
  • 72
pnezis
  • 11,459
  • 1
  • 35
  • 37
  • Oh, how could I miss to see that. This is obviously the best solution for the described problem, however, I chose to stick with the solution provided in the comments to the main question due to it making more sense in my special situation. – athre0z Sep 27 '12 at 14:53
1

An alternative is using QPointer instead of QSharedPointer, citing the documentation:

The QPointer class is a template class that provides guarded pointers to QObject.

A guarded pointer, QPointer, behaves like a normal C++ pointer T *, except that it is automatically set to 0 when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). T must be a subclass of QObject.

Community
  • 1
  • 1
vlp
  • 6,063
  • 2
  • 18
  • 44