我有一个类似树节点的类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;
};
这个类可以有一个父级和一组子级。我在实现addChild
andsetParent
成员函数时遇到了问题:
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));
}
}
我期望会发生什么:
Message::addChild
被调用thisPtr
使用引用计数 1 创建childPtr->parent() != thisPtr
将解决true
childPtr->setParent(thisPtr);
,Message::setParent
被执行并且thisPtr
引用计数将随着共享指针的副本被创建而增加 1。现在thisPtr
的引用计数为 2- 随着
Message::setParent
执行,m_parentPtr = parentPtr;
将增加m_parentPtr
,parentPtr
因此thisPtr
引用计数增加 1;这 3 个智能指针现在的引用计数为 3。 - 执行退出
Message::setParent
并销毁将和parentPtr
的引用计数减1m_parentPtr
thisPtr
- 执行返回
Message::addChild
。现在的引用计数thisPtr
为 2。
实际发生的情况:
当执行退出时,引用计数中的if
语句Message::addChild
thisPtr
再次减少 1,留下thisPtr
的引用计数为 1。这使得一切都在执行存在时中断Message::addChild
,thisPtr
被破坏,因此this
被删除。
我的问题:
为什么当执行退出语句或那里实际发生的情况thisPtr
时引用计数再次减少?...if
Message::addChild