0

我正在为一个简单的“节点”类编写一些 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;)但是当我创建一个调用复制构造函数的实例时,我最终会在程序的最后出现段错误,因为它正在清理。将结构用于链表与类之间的区别对我来说有点小技巧,我认为我在这里遗漏了一些关键。下面是默认构造函数、复制构造函数和重载赋值运算符的实现:

//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;
}

请注意,使用重载分配函数似乎可以正常工作(没有段错误),即使它实际上是相同的代码......我假设这与两个对象在分配发生 之前已经初始化的事实有关?

//This seems to work ok
Node node1;
Node node2;
node2 = node1;

我已经在这个错误上待了几个小时,我必须休息一下。我真的很感激对此的任何见解。谢谢。

4

2 回答 2

1

在复制构造函数循环中,您有这一行:

Node * oldNext = next_;

但是,在循环的第一轮中,值next_可以是,嗯,任何东西,很可能不是NULL。这意味着最后一个节点将有一个非空指针。

将其初始化为NULL循环之前,它应该可以工作。

于 2012-07-31T07:15:11.690 回答
1

您混淆了 List 和 Node 的概念。您应该编写一个管理一系列节点的 List 类。您的 Node 析构函数或多或少是您的 List 析构函数的外观,Node 本身不需要析构函数。

具体出问题的是,您的 Node 析构函数在您编写delete temp;此代码时会递归调用自身,这会删除其余的节点序列,但随后您的 Node 析构函数会循环并尝试再次删除它们。

于 2012-07-31T07:37:39.787 回答