[英]this pointer and QSharedPointer
我有一個類似 class 的樹節點,名為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;
};
這個 class 可以有一個父母和一組孩子。 我在實現addChild
和setParent
成員函數時遇到問題:
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
創建時引用計數為 1childPtr->parent() != thisPtr
將被解析為true
childPtr->setParent(thisPtr);
, Message::setParent
被執行並且thisPtr
引用計數將隨着創建共享指針的副本而增加 1。 現在thisPtr
的引用計數為 2Message::setParent
被執行時, m_parentPtr = parentPtr;
會將m_parentPtr
、 parentPtr
和thisPtr
引用計數增加 1; 這 3 個智能指針現在的引用計數為 3。Message::setParent
並銷毀parentPtr
將m_parentPtr
和thisPtr
的引用計數減 1Message::addChild
。 現在thisPtr
的引用計數是 2。實際發生了什么:
當執行退出Message::addChild
中的if
語句時, thisPtr
引用計數再次減少 1,使thisPtr
的引用計數為 1。這使得一切都中斷,因為當執行存在Message::addChild
時, thisPtr
被銷毀,因此this
被刪除。
我的問題:
為什么thisPtr
引用計數會在執行退出Message::addChild
中的if
語句或那里實際發生的情況時再次減少?...
- 當
Message::setParent
被執行時,m_parentPtr = parentPtr;
將增加m_parentPtr
,parentPtr
,因此thisPtr
引用計數增加1; 這3個智能指針現在的引用計數為3。
5.1。 然后, setParent
構造一個指向引用計數為1的子級的臨時共享指針,並在父級上調用addChild
:
m_parentPtr->addChild(Message::Ptr(this));
5.2。 addChild
創建一個指向引用計數為1的父級的共享指針:
Message::Ptr thisPtr(this);
5.3。 addChild
返回,破壞了5.2的共享指針,破壞了父節點,這破壞了父節點的QSet<Message::Ptr> m_children
成員。
5.4。 5.1的臨時共享指針被破壞,這將破壞子代。
一般來說,您有一個循環引用:父母擁有孩子,而孩子擁有父母,這是內存泄漏和刪除后使用錯誤的秘訣。 構造擁有其他共享指針已經擁有的原始指針的新共享指針是雙重刪除和使用后刪除錯誤的訣竅。 共享的指針不會相互了解,它們的引用計數將獨立變化。 您應該研究QWeakPointer
來打破循環,並研究QEnableSharedFromThis
以安全地獲取指向*this
的共享指針。
請參閱Qt文檔中的 QEnableSharedFromThis。 這應該可以解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.