我正在为一个简单的“Node”类编写一些C ++代码。这基本上是用于管理线性链表的类。我通常使用结构执行此操作,但我正在尝试更好地处理OOP和类。到目前为止,Node类的内容是(注意:String类是我的版本(修剪)典型的“字符串”类,它实现了一个复制构造函数,赋值重载,析构函数等。在测试中它有工作得很好,似乎完全独立):
class Node {
public:
//Constructor
//-----------
Node() : next_(0) {} //inline (String constructor called)
//Destructor
//----------
~Node();
//Copy Constructor
//----------------
Node(const Node &);
//Operator Overload: =
//---------------------
//In conjunction with copy constructor. Protects Class.
Node & operator=(const Node &);
private:
String relatedEntry_;
Node * next_;
};
创建一个实例工作正常(即。Node node;
)但是当我创建一个调用Copy Constructor的实例时,我最终会在程序的最后部分使用segfaults,因为它正在清理。使用链接列表的结构与类之间的区别对我来说有点诡计,我想我在这里缺少一些关键。以下是Default Constructor,Copy Constructor和Overloaded Assignment Operator的实现:
//Constructor inlined
//Destructor
Node::~Node()
{
Node * curr = next_;
while (curr) //cycle through LL and delete nodes
{
Node * temp = curr; //hold onto current
curr = curr->next_; //increment one
delete temp; //delete former current
}
}
//Copy Constructor
Node::Node(const Node & cp)
{
std::cout << "in CopyCon" << std::endl;
relatedEntry_ = cp.relatedEntry_; //calls String class copy constructor/assignment overload
Node * curr = cp.next_; //for clarity, for traversal
while (curr) //copies related entry structure
{
Node * oldNext = next_;
next_ = new Node;
next_->next_ = oldNext; //'next' field (assign prior)
next_->relatedEntry_ = curr->relatedEntry_; //String class copy
curr = curr->next_; //increment
}
}
//OO: =
Node & Node::operator=(const Node & cp)
{
std::cout << "in OO: =" << std::endl;
if (this == &cp)
return *this; //self assignment
delete next_; //delete LL
relatedEntry_ = cp.relatedEntry_; //String Class Assignment Overload
Node * curr = cp.next_; //for clarity, for traversal
while (curr)
{
Node * oldNext = next_; //hold onto old
next_ = new Node;
next_->next_ = oldNext; //set next to old
next_->relatedEntry_ = curr->relatedEntry_; //set this string to cp string
curr = curr->next_; //increment
}
return *this;
}
请注意,使用重载分配函数似乎工作正常(没有segfaults),即使它实际上是相同的代码...我假设它与两个对象已经初始化之前的事实有关/ em>作业发生了吗?
//This seems to work ok
Node node1;
Node node2;
node2 = node1;
我已经在这个bug上呆了几个小时了,我得休息一下。我真的很感激任何洞察力。谢谢。
答案 0 :(得分:1)
在复制构造函数循环中,您有以下行:
Node * oldNext = next_;
然而,在循环的第一轮中,next_
的值可以是任何东西,很可能不是NULL
。这意味着最后一个节点将具有非空指针。
在循环之前将其初始化为NULL
,它应该可以正常工作。
答案 1 :(得分:1)
您将List和Node的概念混淆了。您应该编写一个List类来管理一系列节点。您的Node析构函数或多或少是List析构函数的外观,Node本身不需要析构函数。
特别错误的是你的Node析构函数在你写delete temp;
时递归调用自身这会删除节点序列的其余部分,但是你的Node析构函数会循环并尝试再次删除它们。