C++ 此指针和QSharedPointer
我有一个类似树节点的类,名为C++ 此指针和QSharedPointer,c++,qt,qt5,shared-ptr,qsharedpointer,C++,Qt,Qt5,Shared Ptr,Qsharedpointer,我有一个类似树节点的类,名为Message,如下所示: class Message { public: using Ptr = QSharedPointer<Message>; public: explicit Message(); explicit Message(Message::Ptr parentPtr); explicit Message(const Data &data, Message::Ptr parentPtr = Mess
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;
};
我预期会发生什么:
Message::addChild
被调用thisPtr
创建时引用计数为1childPtr->parent()!=此PTR
将解析为true
childPtr->setParent(thisPtr)
,Message::setParent
将被执行,thisPtr
引用计数将随着共享指针副本的创建而增加1。现在thisPtr
的引用计数为2Message::setParent
时,m_parentPtr=parentPtr
将增加m_parentPtr
,parentPtr
,从而thisPtr
参考计数增加1;这3个智能指针现在的引用计数为3Message::setParent
并销毁parentPtr
将m_parentPtr
和thisPtr的引用计数减少1
Message::addChild
。现在,该PTR的参考计数为2Message::addChild
thisPtr
中的if
语句引用计数再次减少1,使thisPtr
的引用计数保持为1。当执行存在时,Message::addChild
,thisPtr
被销毁,因此This
被删除
我的问题:
为什么当执行退出Message::addChild
中的if
语句时,thisPtr
引用计数再次减少,或者实际发生了什么
以下是它在调试器中的运行方式:
Message::setParent
时,m_parentPtr=parentPtr
将增加m_parentPtr
,parentPtr
,从而thisPtr
参考计数增加1;这3个智能指针现在的引用计数为3setParent
构造一个临时共享指针,指向引用计数为1的子级,并在父级上调用addChild
:
m_parentPtr->addChild(Message::Ptr(this));
5.2addChild
创建指向引用计数为1的父级的共享指针:
Message::Ptr thisPtr(this);
5.3addChild
返回,销毁5.2的共享指针,这将销毁父级,这将销毁父级的QSet m_子级
成员
5.4。5.1的临时共享指针被销毁,这将销毁子级
更一般地说,您有一个循环引用:父母拥有孩子,孩子拥有他们的父母,这是导致内存泄漏和删除bug后使用的一个处方。构建新的共享指针(拥有其他共享指针已经拥有的原始指针)是双重删除和删除错误后使用的方法;共享指针彼此不了解,它们的引用计数将独立变化。您应该进行调查,以打破这种循环,并安全地获得指向
*此的共享指针。您不能将*此的所有权移交给QSharedPointer
(您甚至多次这样做)。阅读。哇,这是一个令人讨厌的动画-难道你不能把它转换成文本形式吗?@JesperJuhl嗯,这正是我在这7点上所做的,我期待着会发生的事情…@molbdnilo是的,你是对的!哦,我忘了说“然后扔掉那个讨厌的周年纪念”;-)但也许那只是我。。
Message::Ptr thisPtr(this);