将std :: shared_ptr转换为QPointer

Tom*_*ica 5 c++ shared-ptr c++11 qpointer

我们的应用程序的设计非常差-它既使用std::shared_ptr和QObject亲子关系来管理我们的一些对象。当QObject::~QObject删除其子对象,然后shared_ptr尝试也将其删除时,这会导致段错误。

我们讨论了此问题,但目前尚无轻松解决此问题的方法,因此在我们对其进行修复之前,我将需要使用一些肮脏的技巧。

现在我有一个std::shared_ptr<MyObject> getMyObjectPtr()功能。我需要将结果放入QPointer<MyObject>-QPointers是弱指针,仅指示他们管理的QObject是否已删除。我无法以任何方式更改该功能,它将破坏整个应用程序。

我使用自定义脱发器尝试了一些技巧,但这似乎行不通。

// 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());
Run Code Online (Sandbox Code Playgroud)

但是,以这种方式,一旦函数结束,指针将被删除。大概,自定义脱机器与数据一起移动。

Jer*_*ner 0

我不认为这个问题有任何好的解决方案,除了开始重构你的代码,以便任何给定的对象要么通过 QObject 样式的父/子关系进行管理,要么通过share_ptr <> 引用计数来管理——但决不能同时使用这两种方法。同一个对象。这两种方法彼此差异太大,很难协调一致。

也就是说,为了完成上述任务而无需太多重新设计,您可以做的一件事是:不要使用指向QObject的共享指针<> ,而是使共享指针指向(非基于 QObject 的) ),QObject 的shared_ptr 管理的子对象。

也就是说,代替这个:

class MyQObject : public QObject 
{
public:
   MyQObject(int x, int y, int z, QObject * parent)
      : QObject(parent), m_x, m_y, m_z {/* empty */}

   int getX() const {return m_x;}
   int getY() const {return m_y;}
   int getZ() const {return m_z;}

private:
   int m_x, m_y, m_z;
};

[...]

QObject * parent = new QObject;
shared_ptr<MyQObject> ptr(new MyQObject(1,2,3,parent));   // d'oh!  trouble!
Run Code Online (Sandbox Code Playgroud)

做这样的事情:

class MyData
{
public:
   MyData(int x, int y, int z) : m_x(x), m_y(y), m_z(z)

   int getX() const {return m_x;}
   int getY() const {return m_y;}
   int getZ() const {return m_z;}

private:
   int m_x, m_y, m_z;
};

class MyQObject : public QObject
{
public:
   MyQObject(int x, int y, int z, QObject * parent)
      : QObject(parent), m_data(make_shared<MyData>(x,y,z)) {/* empty */}

   int getX() const {return m_data->getX();}
   int getY() const {return m_data->getY();}
   int getZ() const {return m_data->getZ();}

   shared_ptr<MyData> getData() {return m_data;}

private:
   shared_ptr<MyData> m_data;
};

[...]

QObject * parent = new QObject;
QObject * myObj = new MyQObject(1,2,3,parent));
shared_ptr<MyData> ptr(myObj->getData());   // no problem!
Run Code Online (Sandbox Code Playgroud)

这样,您的 Qt 样式代码就可以访问 QObject 和 MyData,而 shared_ptr 样式代码可以访问 MyData。(当然,如果您的shared_ptr样式代码还需要访问QObject本身,那么您可能会运气不好,因为Qt将决定何时何地删除QObject并且不会尊重shared_ptr语义)