gpt4 book ai didi

c++ - 这个指针和 QSharedPointer

转载 作者:行者123 更新时间:2023-11-30 03:34:45 27 4
gpt4 key购买 nike

我有一个名为 Message 的树节点类,如下所示:

class Message
{
public:
using Ptr = QSharedPointer<Message>;

public:
explicit Message();
explicit Message(Message::Ptr parentPtr);
explicit Message(const Data &data, Message::Ptr parentPtr = Message::Ptr());

void setParent(Message::Ptr parentPtr);
Message::Ptr parent() const;
bool hasParent() const;

QSet<Message::Ptr> children() const;
void setChildren(const QSet<Message::Ptr> &children);
bool hasChildren() const;

Data data() const;
void setData(const Data &data);

private:
void addChild(Message::Ptr childPtr);
void removeChild(Message::Ptr childPtr);

private:
Message::Ptr m_parentPtr;
QSet<Message::Ptr> m_children;
Data m_data;
};

这个类可以有一个父类和一组子类。我在实现 addChildsetParent 成员函数时遇到问题:

void Message::addChild(Message::Ptr childPtr)
{
if (!m_children.contains(childPtr)) {
m_children.insert(childPtr);
}

Message::Ptr thisPtr(this);

if (childPtr->parent() != thisPtr) {
childPtr->setParent(thisPtr);
}
}

void Message::setParent(Message::Ptr parentPtr)
{
if (m_parentPtr != parentPtr) {
m_parentPtr = parentPtr;

m_parentPtr->addChild(Message::Ptr(this));
}
}

我期望会发生什么:

  1. Message::addChild 被调用
  2. thisPtr 创建时引用计数为 1
  3. childPtr->parent() != thisPtr 将解析为 true
  4. childPtr->setParent(thisPtr);Message::setParent被执行,thisPtr引用计数将增加1作为拷贝创建共享指针。现在 thisPtr 的引用计数为 2
  5. 随着 Message::setParent 被执行,m_parentPtr = parentPtr; 将增加 m_parentPtr, parentPtr 从而thisPtr 引用计数减 1;这 3 个智能指针现在的引用计数为 3。
  6. 执行退出 Message::setParent 并销毁 parentPtrm_parentPtrthisPtr 的引用计数减 1
  7. 执行返回到 Message::addChild。现在 thisPtr 的引用计数是 2。

实际发生了什么:

当执行退出 Message::addChild 中的 if 语句时 thisPtr 引用计数再次减 1,留下 thisPtr 的引用计数为 1。这使得一切都中断,因为当执行存在 Message::addChild 时,thisPtr 被销毁,因此 this 被删除.

我的问题:

当执行退出 Message::addChild 中的 if 语句时,为什么 thisPtr 引用计数会再次减少,或者那里实际发生了什么? ..

这是它在调试器中的运行方式: enter image description here

最佳答案

  1. As Message::setParent gets executed, m_parentPtr = parentPtr; will increase m_parentPtr, parentPtr and thus thisPtr reference counts by 1; these 3 smart pointers now have a reference count of 3.

5.1。然后,setParent构造一个指向子引用计数为 1 的临时共享指针并调用 addChild在 parent 身上:

m_parentPtr->addChild(Message::Ptr(this));

5.2。 addChild创建一个指向父级的共享指针引用计数为 1:

Message::Ptr thisPtr(this);

5.3。 addChild返回,销毁 5.2 的共享指针,这会销毁父级,这会销毁父级的 QSet<Message::Ptr> m_children。成员(member)。

5.4。 5.1的临时共享指针被销毁,从而销毁了 child 。

更一般地说,您有一个循环引用: parent 拥有 child , child 拥有 parent ,这是内存泄漏和删除后使用错误的秘诀。构造新的共享指针拥有其他共享指针已经拥有的原始指针是双重删除和删除后使用错误的秘诀;共享指针不会相互了解,它们的引用计数将独立变化。你应该调查 QWeakPointer 打破循环和 QEnableSharedFromThis 安全地获取指向 *this 的共享指针.

关于c++ - 这个指针和 QSharedPointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41837870/

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