Our application is VERY poorly designed - it uses both std::shared_ptr
and QObject
parent-child relationship to manage some of our objects. This leads to segfaults when QObject::~QObject
deletes its child objects and THEN shared_ptr
tries to delete it also.
We discussed this but currently see no way to fix this easily so I'll need to use few dirty hacks until we fix it.
Now what I have is a std::shared_ptr<MyObject> getMyObjectPtr()
function. I need to put the result into QPointer<MyObject>
- QPointers are weak pointers that merely indicate if the QObject they manage is deleted. I cannot change that function in any way, it would break the whole application.
I tried few hacks with custom dealocator but that doesn't seem to work.
// get the shared_ptr from inacessible API
std::shared_ptr<MyObject> oldPtr(getMyObjectPtr());
// create a new pointer that never deletes it's value
std::shared_ptr<MyObject> newPtr(nullptr, [](MyObject*) {});
// Move pointer from old to new non-deleting ptr
newPtr.swap(oldPtr);
QPointer<MyObject> qptr(newPtr.get());
However this way, the pointer gets deleted once my function ends. Presumably, the custom dealocator moves along with the data.
I don't think there is any good solution to this problem, other than to start refactoring your code so that any given object is either managed via QObject-style parent/child relationships, or shared_ptr<> reference counting -- but never both in the same object. The two approaches are just too different from each other to easily reconcile.
That said, one thing that you might be able to do in order to accomplish the above without too much redesign is this: instead of having a shared_ptr<> that points to your QObject, make the shared_ptr point to a (non-QObject-based), shared_ptr-managed sub-object of the QObject.
That is, instead of this:
do something like this:
That way your Qt-style code has access to both the QObject and the MyData, while the shared_ptr-style code has access to the MyData. (Of course, if your shared_ptr-style code needs also access to the QObject itself, you're probably out of luck, since Qt will decide when and where to delete the QObject and won't respect the shared_ptr semantics)