我正在学习智能指针,还有什么比在堆上实现简单结构(如链表)更好的了。
我创建了一个链接列表结构,如下所示...
// linked list node definition
#ifndef __LINKED_LIST_NODE_H
#define __LINKED_LIST_NODE_H
class LinkedListNode {
friend class LinkedList;
public:
int m_value;
LinkedListNode * m_pNext;
public:
LinkedListNode();
LinkedListNode(int);
LinkedListNode(const LinkedListNode &);
~LinkedListNode();
};
#endif
// linked list definition
#ifndef __LINKED_LIST_H
#define __LINKED_LIST_H
class LinkedList {
LinkedListNode * m_pHead;
LinkedListNode * m_pTail;
public:
LinkedList();
LinkedList(int);
LinkedList(const LinkedList &);
~LinkedList();
void PrintList() const;
void AddItem(int);
void RemoveItem(int);
LinkedListNode * FindNode(int) const;
LinkedListNode * FindMin() const;
LinkedListNode * FindMax() const;
};
#endif
这是LinkedListNode和LinkedList类的必需方法(构造函数和析构函数),以查看其外观(IIRC这些应该正确)...
// list node
LinkedListNode::LinkedListNode()
{
m_value = 0;
m_pNext = nullptr;
}
LinkedListNode::LinkedListNode(int value)
{
m_value = value;
m_pNext = nullptr;
}
LinkedListNode::LinkedListNode(const LinkedListNode & copyNode)
{
m_value = copyNode.m_value;
m_pNext = copyNode.m_pNext;
}
LinkedListNode::~LinkedListNode()
{
// not needed, no dynamic allocation
}
// linked list
LinkedList::LinkedList()
{
m_pHead = nullptr;
m_pTail = m_pHead;
}
LinkedList::LinkedList(int value)
{
std::shared_ptr<LinkedListNode>newNode{ new LinkedListNode(value) };
m_pHead = newNode.get();
m_pHead->m_pNext = nullptr;
m_pTail = m_pHead;
}
LinkedList::LinkedList(const LinkedList & copyList)
{
if (copyList.m_pHead == nullptr)
{
m_pHead = nullptr;
m_pTail = m_pHead;
}
else
{
std::shared_ptr<LinkedListNode>NodeResource{ new LinkedListNode(*copyList.m_pHead) };
LinkedListNode * tempNode = NodeResource.get();
m_pHead = tempNode;
while (tempNode->m_pNext != nullptr)
{
std::shared_ptr<LinkedListNode>NodeResourceNext{ new LinkedListNode(*tempNode->m_pNext) };
tempNode->m_pNext = NodeResourceNext.get();
tempNode = NodeResourceNext.get();
}
m_pTail = tempNode;
}
}
LinkedList::~LinkedList()
{
// not needed, allocating using smart pointers
}
现在,LinkedList类包含AddItem方法,其主体为:
void LinkedList::AddItem(int value)
{
std::shared_ptr<LinkedListNode>newNode{ new LinkedListNode(value) };
if (m_pHead == nullptr) // linked list is empty
{
m_pHead = newNode.get();
m_pTail = newNode.get();
}
else
{
m_pTail->m_pNext = newNode.get();
m_pTail = newNode.get();
}
}
而且我不知道为什么,但是当我尝试向链接列表中添加项目时,当您超出方法范围时,似乎newNode变量将被删除。
这是我尝试调试程序时的样子...
首先,我们从一个空的链接列表开始
然后在AddItem函数中,我得到以下结果(看起来m_pHead和m_pTail正确地指向堆上新创建的newNode。
但是当AddItem()方法超出范围时,这就是我剩下的
我以为,一旦没有引用指针,std::share_ptr将被删除。在我的情况下,newNode被两个指针m_pHead和m_pTail引用。离开AddItem()方法后,它真的被删除了吗?还是我的代码中没有发现一个缺陷?
伙计们,非常感谢您的投入。
最佳答案
您正在将newNode.get()
分配给LinkedListNode*
的原始指针(LinkedListNode
)成员。
这是不正确的,因为shared_ptr
(至少在这种情况下)拥有底层指针。当超出范围时,关联的内存将被释放,但是您的LinkedListNode
仍然具有以前分配的内存的成员。
您可能应该更改LinkedListNode
的定义,以使其LinkedListNode*
成员改为shared_ptr<LinkedListNode>
,以确保只要实例存在就可以引用基础内存。