我们的应用程序设计非常糟糕--它同时使用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());但是,这样,一旦我的函数结束,指针就会被删除。据推测,自定义释放器与数据一起移动。
发布于 2017-07-03 14:41:52
我认为这个问题没有任何好的解决方案,只是开始重构代码,以便通过QObject风格的父/子关系或shared_ptr<>引用计数来管理任何给定的对象--但绝不是同时存在于同一个对象中。这两种方法太不一样了,很难调和。
尽管如此,为了在不进行太多重新设计的情况下完成上述工作,您可能可以做的一件事是:与其让shared_ptr<>指向您的QObject,不如让shared_ptr指向(非基于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!做这样的事:
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!这样,Qt样式的代码可以访问QObject和MyData,而shared_ptr风格的代码可以访问MyData。(当然,如果您的shared_ptr风格的代码也需要访问QObject本身,那么您可能就不走运了,因为Qt将决定何时何地删除QObject,并且不尊重shared_ptr语义)
https://stackoverflow.com/questions/44885112
复制相似问题