gpt4 book ai didi

c++ - 将 std::shared_ptr 转换为 QPointer

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:50:13 24 4
gpt4 key购买 nike

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

我们讨论过这个问题,但目前没有办法轻松解决这个问题,所以在我们解决它之前,我需要使用一些肮脏的技巧。

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

我尝试了一些自定义解除分配器的 hack,但似乎没有用。

// 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());

但是,一旦我的函数结束,指针就会被删除。据推测,自定义解除分配器会随着数据一起移动。

最佳答案

我认为这个问题没有任何好的解决方案,除了开始重构您的代码,以便通过 QObject 样式的父/子关系管理任何给定对象, shared_ptr <> 引用计数——但绝不会在同一个对象中。这两种方法彼此差异太大,无法轻松调和。

就是说,为了在不进行过多重新设计的情况下实现上述目标,您可以做的一件事是:与其使用指向您的 QObject 的 shared_ptr<>,不如让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 语义)

关于c++ - 将 std::shared_ptr 转换为 QPointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44885112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com