首页 > 解决方案 > C++链表节点引用自身

问题描述

我正在创建一个将卡片保存在卡片组中的链接列表。它只有一个头,因为我不需要尾巴。当我添加第一张卡时,一切正常,当我添加第二张卡时,它将自己设置为下一张并基本上创建了一个无限列表。

我不知道为什么会这样。我已经单步执行了代码,每当在第二张卡片上调用 addCard() 方法时,头部就会神奇地变为那张卡片,而无需我这样做。这听起来很疯狂,但我找不到任何其他解释。任何帮助深表感谢。

标题

#pragma once
#include "Card.h"
class Deck {
public:
    bool isEmpty();
    ~Deck();
    void addCard(Card); //at top
    Card removeCard(); //from top
    void addAllCards(); //All 52 cards
    void print(); //print all the cards
private:
    int count = 0;
    Card* head{ NULL };
};

定义

#include "Deck.h"
#include <iostream>

bool Deck::isEmpty() {
    return this->count == 0;
}


void Deck::addCard(Card card) {
    if (isEmpty()) {
        this->head = &card;
    }
    else {
        card.next = this->head;
        this->head = &card;
    }
    count += 1;
}

Card Deck::removeCard() {
    if (!isEmpty()) {
        count -= 1;
        Card temp = *head;
        head = head->next;
        return temp;
    }
}

void Deck::addAllCards() {
    for (int suit = 0; suit < 4; suit++) {
        for (int rank = 0; rank < 13; rank++) {
            Card newCard = Card(suit, rank);
            this->addCard(newCard);
        }
    }
}

void Deck::print() {
    Card* current = head;
    while (current != NULL) {
        std::cout << current->stringSuitAndRank() << std::endl;
        current = current->next;
    }
}

Deck::~Deck() {
    while (!isEmpty()) {
        removeCard();
    }
}

司机

#include <iostream>
#include <string>
#include "Card.h"
#include "Deck.h"

using namespace std;

int main()
{
    Card myCard1{ 2, 4 };
    Card myCard2{ 4, 5 };

    {
        Deck myDeck;

        myDeck.addCard(myCard1);
        myDeck.addCard(myCard2);

        cout << endl << "Printing deck..." << endl;
        myDeck.print();

        myDeck.removeCard();
        myDeck.removeCard();

        cout << endl << "Printing deck..." << endl;
        myDeck.print();

        cout << endl << "Adding all cards..." << endl << endl;
        myDeck.addAllCards();

        cout << endl << "Printing deck..." << endl;
        myDeck.print();
    }

    system("pause");
}

编辑:当我到达列表末尾时,我在 print 方法中也遇到了读取访问冲突。我假设它与 nullptr 相关,但帮助再次得到重视。

标签: c++linked-list

解决方案


void Deck::addCard(Card card) {

card是此类方法的参数。方法参数实际上是方法中的局部对象。card这与声明在此方法中调用的对象没有什么不同。唯一的区别是实际对象是从调用此方法的人那里复制的,但在所有其他方面,它与card在此方法中声明的被调用变量没有什么不同。

就像在这个方法中声明的任何其他变量一样,当它返回这个被调用的对象时,它card会被销毁。它会消失的。不会再有了。它将不复存在。这将是一个前对象。

this->head = &card;

这部分addCard()存储了一个指向成员card的指针。head到目前为止,一切都很好。但是,不久之后,这个card物体将不复存在。看上面。这成为一个指向已销毁对象的指针。下一次addCard()被召唤,欢闹随之而来。

要解决此问题,您需要重新阅读 C++ 书中解释 C++ 中的对象如何工作、何时创建以及何时销毁的章节。如果您的本练习的目标是自己练习实现链接列表,并且您不希望利用 C++ 库的容器,那么您将需要使用newdelete动态创建对象,因此当此方法返回时,这些对象将不会消失。他们不会再没有了。它们不会不复存在。它们不会是前对象。


推荐阅读