【问题标题】:How can I set a listnode value to Null without getting this error?如何将 listnode 值设置为 Null 而不会出现此错误?
【发布时间】:2020-08-11 11:21:49
【问题描述】:

我想花一点时间感谢 Remy Lebeau 为我编辑了这篇文章。

我的编译器给了我这个错误:

main.cpp:93:20:错误:从“int”到“listnode*”的无效转换[-fpermissive]
临时 -> 下一个 = NULL;

这是在InsertTail 方法中。

我不明白问题出在哪里。有人可以帮我解决这个问题吗?我只需要能够将 listnode 值设置为 Null。

这是我的 C++ 文件:

program4.cpp

#include <iostream>

using namespace std;

#undef NULL

const int NULL = 0;

typedef int element;

const element SENTINEL = -1;

element read_element();

class listnode{

    public:
        element data;
        listnode * next;

    };

class LList {

    private:
        listnode * head;
        listnode * tail;

    public:
        LList();
        ~LList();
        void Print();
        void InsertHead(element thing);
        void InsertTail(element thing);
        element DeleteHead();
        void ReadForward();
        void ReadBackward();
        void Clean();
        void Steal(LList & Victim);
        void Append(LList & Donor);
        void Duplicate(LList & Source);
        void Reverse();

    };

void LList::Print(){

    // PRE: the N. O. LList is valid
    // POST: the N. O. LList is unchanged, and its elements
    //      have been displayed

    listnode * temp;

    temp = head;
    while (temp != NULL){
        cout << temp -> data << endl;
        temp = temp -> next;
        }

    }

void LList::ReadForward(){

    // PRE: the N. O. LList is valid
    // POST: the N. O. LList is valid, all of its previous
    //      listnodes have been deleted, and it now
    //      consists of new listnodes containing elements
    //      given by the user in forward order

    element userval;

    Clean();
    cout << "Enter elements, " << SENTINEL << " to stop: ";
    userval = read_element();
    while (userval != SENTINEL){
        InsertTail(userval);
        userval = read_element();
        }

    }

void LList::InsertTail(element thing){

    // PRE: the N. O. LList is valid
    // POST: the N. O. LList is unchanged, except that a
    //      new listnode containing element thing has been
    //      inserted at the tail-end of the list

    listnode * temp;

    temp = new listnode;
    temp -> data = thing;
    temp -> next = NULL;
    if (head == NULL)
        head = temp;
    else
        tail -> next = temp;
    tail = temp;

    }

element read_element(){

    // PRE: the user must enter a series of zero or 
    //      more non-valid element values, followed
    //      by a valid element value 
    //
    // POST: all entered non-valid element values will
    //      be successfully discarded, and the first
    //      valid element value entered will be 
    //      returned

    element userval;

    cin >> boolalpha >> userval;
    while (! cin.good()){
        cin.clear();
        cin.ignore(80, '\n');
        cout << "Invalid data type, should be an element, "
            << "try again: ";
        cin >> boolalpha >> userval;
        }
    return userval;
    }

void LList::ReadBackward(){

    // PRE: the N. O. LList is valid 
    // POST: the N. O. LList is valid, all of its previous
    //      listnodes have been deleted, and it now
    //      consists of new listnodes containing elements
    //      given by the user in backward order

    element userval;

    Clean();
    cout << "Enter elements, " << SENTINEL << " to stop: ";
    userval = read_element();
    while (userval != SENTINEL){
        InsertHead(userval);
        userval = read_element();
        }

    }


void LList::InsertHead(element thing){

    // PRE: the N. O. LList is valid
    // POST: the N. O. LList is unchanged, except that a 
    //      new listnode containing element thing has been
    //      inserted at the head-end of the list 

    listnode * temp;

    temp = new listnode;
    temp -> data = thing;
    temp -> next = head;
    if (head == NULL)
        tail = temp;
    else
        ;
    head = temp;

    }


void LList::Clean(){
    // PRE: the N. O. LList is valid 
    // POST: the N. O. LList is valid and empty, and all of 
    //      its listnodes have been deleted

    while (head != NULL)
        DeleteHead();

    }

element LList::DeleteHead(){

    // PRE: the N. O. LList is valid and not empty
    // POST: the N. O. LList is unchanged, except that the 
    //      listnode at the head end of the list has been
    //      deleted, and its data element has been
    //      returned

    listnode * temp;
    element thing;

    temp = head;
    head = head -> next;
    thing = temp -> data;
    delete temp;
    return thing;
    }

LList::LList(){

    // PRE: none
    // POST: the N. O. LList is valid and empty

    head = NULL;
    }

LList::~LList(){

    // PRE: the N. O. LList is valid 
    // POST: the N. O. LList is valid and empty, and its 
    //      listnodes have been deleted 

    Clean();
    }

void LList::Steal(LList & Victim){

    // PRE: the N. O. and Victim LLists are valid
    // POST: the Victim LList is valid and empty
    //      the N. O. LList is valid, all of its previous
    //      listnodes have been deleted, and it now
    //      consists of the listnodes originally on the 
    //      Victim LList

    Clean();
    head = Victim.head;
    tail = Victim.tail;
    Victim.head = NULL;

    }

void LList::Append(LList & Donor){

    // PRE: the N. O. and Donor LLists are valid 
    // POST: the Donor LList is valid and empty
    //      the N. O. LList is valid, and it now consists
    //      of its own original listnodes followed by the 
    //      listnodes originally on the Donor LList

    if (head != NULL)
        tail -> next = Donor.head;
    else
        head = Donor.head;
    if (Donor.head != NULL)
        tail = Donor.tail;
    else
        ;
    Donor.head = NULL;
    }

void LList::Duplicate(LList & Source){

    // PRE: the N. O. and Source LLists are valid 
    // POST: the Source LList is unchanged 
    //      the N. O. LList is valid, all of its previous
    //      listnodes have been deleted, and it now
    //      consists of listnodes containing the same
    //      elements and in the same order as on the 
    //      Source LList

    listnode * temp;

    Clean();
    temp = Source.head;
    while (temp != NULL){
        InsertTail(temp -> data);
        temp = temp -> next;
        }

    }

void LList::Reverse(){

    // PRE: the N. O. LList is valid 
    // POST: the N. O. LList is unchanged, except its 
    //      elements are in reverse order 

    listnode * temp;
    LList Helper;

    temp = head;
    while (temp != NULL){
        Helper.InsertHead(temp -> data);
        temp = temp -> next;
        }
    Steal(Helper);

    }

iny main(){

    cout << "creating/constructing LList object L" << endl;
    LList L;
    cout << "L has been created/constructed" << endl;

    cout << "L is calling its print method" << endl;
    L.Print();
    cout << "L has been printed" << endl;

    cout << "L is calling its ReadForward method" << endl;
    L.ReadForward();
    cout << "L has been read forward" << endl;

    cout << "L is calling its Print method" << endl;
    L.Print();
    cout << "L has been printed" << endl;

    cout << "L is calling its ReadBackward method" << endl;
    L.ReadBackward();
    cout << "L has been read backward" << endl;

    cout << "L is calling its Print method" << endl;
    L.Print();
    cout << "L has been printed" << endl;

    cout << "L is calling its Clean method" << endl;
    L.Clean();
    cout << "L has been cleaned" << endl;

    cout << "L is calling its Print method" << endl;
    L.Print();
    cout << "L has been printed" << endl;

    }

【问题讨论】:

  • 显示一个演示问题的最小完整程序。
  • 我已经写了一个指向我的程序文件的链接。
  • 删除链接并在您的问题中输入相关代码。
  • 鉴于您在前几行中编写的代码,我很惊讶您甚至不得不问这个问题。无论如何,在现代 C++ 中,我们使用 nullptr 而不是 NULL
  • 您不能将int 变量分配给没有显式类型转换的指针,例如:temp-&gt;next = reinterpret_cast&lt;listnode*&gt;(NULL);。但是,数字文字 0(它是一个编译时常量)可以按原样分配给任何指针,而这正是 NULL 通常默认定义的内容。你根本不应该是#undefing NULL。不过,在 C++11 及更高版本中,您确实应该改用 nullptr

标签: c++ linked-list null-pointer


【解决方案1】:

这段代码出错的原因

#undef NULL

const int NULL = 0;

目前尚不清楚您决定使用它的原因。但为了避免错误,只需删除这两行即可。

此声明

const int NULL = 0;

不引入空指针常量。

此外,您可以使用nullptr,而不是NULL

注意listnode 类应该是LList 类的私有成员。

例如

class LList {

    private:

        struct listnode{
            element data;
            listnode * next;
        } *head = nullptr, *tail = nullptr;
        //...

【讨论】:

  • 这就是我的讲师笔记中的内容。只是问如果它们是私人的,我不会无法在课堂外使用它们吗?在它们公开的情况下处理它们会更快,我不认为将它们设为私有有什么意义。为什么最好将它们保密?
  • @PersonMichael 是类实现。您不应该在类 LList 之外使用节点的定义。
  • 即使它们是在 LList 类的私有部分创建的,将它们放在 Listnode 类的公共部分仍然很糟糕。我理解正确吗?或者你的意思是整个班级应该是一个私人成员。
猜你喜欢
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多