使用非引用返回类型返回* this会更改调用对象中的值

时间:2017-06-06 11:11:32

标签: c++

我试图用c ++实现一个链表类来更好地理解它们,但是我遇到了一些我觉得很奇怪的东西。我使用Visual Studio进行了调试,以查看下面描述的结果。

我的问题是在我的函数appendNode返回* this之前使用非引用返回类型:

list<T> list<T>::appendNode(T value) {}

调用对象的head节点中的值被设置为正确的值,但是在返回函数之后,调用对象的head节点中的值有垃圾,或者至少肯定不是我设置它们的值。我的head-&gt;节点指针总是设置为0xddddddd,我的程序在第二次调用appendNode时崩溃。

我的解决方案是让它返回一个参考:

list<T> &list<T>::appendNode(T value) {}

解决方案有效,所有值都正确,程序运行正常。

liOne的地址在每次迭代后都没有改变,因此它仍然具有相同的头部值,并且head仍然指向同一个节点。我已经检查了调试器中的所有内容。

我的问题是,为什么调用对象的head成员中的值被设置为带有非引用返回类型的垃圾?

我的代码使用非引用返回类型:

#ifndef LIST_H
#define LIST_H

#include <iostream>

template<class T>
class list
{
private:
    class ListNode
    {
    public:
        T value;
        ListNode * node;
    };
    ListNode * head;
public:
    list();
    list(T value);
    ~list();
    list<T> appendNode(T value);
    list<T> insertNode(T value);
    list<T> deleteNode(T value);
    void displayList() const;
};

/*
    Constructor list() creates an empty list with the head pointed to null
 */
template <class T>
list<T>::list()
{
    head = nullptr;
}

/*
    Constructor list(T value) creates a list and creates the first node with
        the value value.
    Parameters:
        T value : the value of the first node created is initialized with
 */
template <class T>
list<T>::list(T value)
{
    head = new ListNode();
    head->value = value;
    head->node = nullptr;
}

/*
    appendNode adds a new node to the end of the list
    Parameters:
        T value - the value to place in the new node
    Return:
        returns this for chain calling
 */
template <class T>
list<T> list<T>::appendNode(T value)
{
    ListNode * newNode = new ListNode();
    newNode->value = value;
    newNode->node = nullptr;

    ListNode * nextNode = nullptr;

    if (!head)
    {
        head = newNode;
    }
    else
    {
        nextNode = head;
        while (nextNode->node)
        {
            nextNode = nextNode->node;
        }
        nextNode->node = newNode;
    }

    return *this;
}

/*
    displayList displays the list contents
 */
template <class T>
void list<T>::displayList() const
{
    ListNode * currNode = head;

    while (currNode)
    {
        std::cout << currNode->value << " ";
        currNode = currNode->node;
    }
}

template <class T>
list<T>::~list()
{
    ListNode * currNode = head;
    ListNode * nextNode = nullptr;

    while (currNode)
    {
        nextNode = currNode->node;

        delete currNode;

        currNode = nextNode;
    }
}

#endif

驱动:

    #include <iostream>

#include "list.h"

int main(int argc, char * argv[])
{
    list<int> liOne;
    list<int> liTwo(0);

    liOne.appendNode(3);
    liOne.appendNode(4);

    liTwo.appendNode(1);
    liTwo.appendNode(2);

    liOne.displayList();
    std::cout << std::endl;

    liTwo.displayList();
    std::cout << std::endl;

    std::cout << "Press <ENTER> to exit...";
    std::cin.get();
    return 0;
}

0 个答案:

没有答案