【问题标题】:LinkedList implementation add method[C++] [duplicate]LinkedList 实现添加方法[C++] [重复]
【发布时间】:2013-07-09 03:19:00
【问题描述】:

大家好,我正在用 c++ 中的类实现 LinkedList,到目前为止,我只完成了节点类和添加方法。但它不起作用,例如我添加了一个新元素,当我检查第一个指针时,它指向我刚刚添加的最后一个元素......

节点类:

template<class T>
class Node
{
private:
    T element;
public:
    Node<T> *next;

    Node( T e ){
        element = e;
        next = NULL;
    }

    friend ostream& operator<<(ostream& os, const Node<T>& nd)
    {
        os << nd.element;
        return os;
    }   

};

还有 LinkedList 类:

 template<class T>
 class LinkedList{

    private:
        int size;

    public: 
        Node<T> *first;
        Node<T> *last;          

        LinkedList(){
            first = NULL;
            last = NULL;
            size = 0;
        }

        void add( T element ){
            Node<T> n (element);

            if( size == 0 ){
                first = &n;
            }else{
                last->next = &n;
            }
            last = &n;
            size++;     
        }

        int getSize(){
            return size;
        }


   };

例如,我主要做以下事情:

LinkedList<int> list;

list.add(5);
list.add(7);


cout << *list.first;

它显示'7'作为第一个元素......

提前致谢。

【问题讨论】:

  • 一个非常重要的问题是你添加的节点是一个本地对象,即它只存在于add()函数内部。您正在获取其地址并尝试将其存储在列表中,但该地址将在 add() 返回后立即失效。
  • 那我应该怎么添加呢?
  • 最简单的直接修复方法是使用Node&lt;T&gt; *n = new Node&lt;T&gt;(element); 代替Node&lt;T&gt; n(element),然后使用n 代替&amp;n。但是您还需要确保在将节点对象从列表中删除(或清除或销毁列表时)时 delete 。因此,更好的解决方案是将next 指针声明为std::unique_ptr&lt;Node&lt;T&gt;&gt;,将它们创建为unique-ptr 并将它们分别移动到firstlast-&gt;next

标签: c++ class pointers linked-list


【解决方案1】:

你不能这样做。 “this”是指存储一个指向本地范围 Node 实例的指针,并期望该对象在其原始范围之外持续存在:

    void add( T element ){
        Node<T> n (element);     // This will only exist for the function's duration

        if( size == 0 ){
            first = &n;          // <-- naughty
        }else{
            last->next = &n;     // <-- naughty
        }
        last = &n;               // <-- naughty
        size++;     
    }

如你所见,你一直很顽皮。一旦函数退出,该节点将被删除。实际上,它只存在于堆栈中,所以它就消失了。幸运的是,当您再次调用该函数时,您恰好得到了相同的堆栈地址,因此看起来您的第一个节点已更改。

那你是做什么的?在堆上分配:

    void add( T element ){
        Node<T> *n = new Node<T>(element);

        if( size == 0 ){
            first = n;
        }else{
            last->next = n;
        }
        last = n;
        size++;     
    }

这不再是顽皮了,您可以继续犯其他与指针相关的错误,这是 C 或 C++ 程序员的基本通行仪式。 =)

确保当你完成你的链表后,你爬过它并delete每个节点释放你分配的内存。

【讨论】:

  • 非常感谢,正是我所需要的。
猜你喜欢
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
相关资源
最近更新 更多