使用自定义类的c++初始化错误

Initialization error using custom classes C++

本文关键字:c++ 初始化 错误 自定义      更新时间:2023-10-16

在尝试初始化时,我一直在"Rainfall most = NULL;"行上得到错误。不能转换为降雨量。我不知道我做错了什么。一共有四个文件,如有任何帮助,我将不胜感激。

主要

    // This program demonstrates the linked list template.
#include <iostream>
#include "RainfallList.h"
#include "Rainfall.h"
using namespace std;
int main()
{
    // Define a LinkedList object.
    RainfallList<Rainfall> list;
    Rainfall most = NULL;
    //Rainfall least = NULL;
    int entries = 0;
    bool marker = false;
    int month = 0;
    int year = 0;
    double rainfall = 0.0;
    double total = 0.0;
    cout << "Enter the number of entries you would like: ";
    cin >> entries;
    //Create linked list of values
    for(int i=1; i<=entries; i++){
        marker=false;
        while(marker==false){
            cout << "Enter the month for entry " << i << " (1-12): ";
            cin >> month;
            cout << "Enter the year for entry " << i << " (2010-2013): ";
            cin >> year;
            cout << "Enter the rainfall for entry " << i << " (inches): ";
            cin >> rainfall;
            if(month>0 && month<13 && year>2009 && year<2014 && rainfall>=0){
                marker=true;
            }else{
                cout << endl << endl << "**ERROR** Make sure the month is a value from 1-12, the year is 2010-2013, and rainfall is 0 or greater!" << endl << endl;
            }
        }
        Rainfall value(year, month, rainfall);
        list.appendNode(value);
    }

    list.displayList();

    //find average rainfall
    total = list.getAvg();
    cout << "The total amount of rainfall is " << total << " inches." << endl;
    cout << "The average rainfall is " << total/entries << " inches" << endl;

    //find the month with the highest rainfall
    most = list.getMost();
    cout << "The most rainfall happened in " << most.getMonth() << " of " << most.getYear() << " where it rained " << most.getRainfall() << " inches." << endl;

    //find the month with the lowest rainfall
    most = list.getLeast();
    cout << "The most rainfall happened in " << most.getMonth() << " of " << most.getYear() << " where it rained " << most.getRainfall() << " inches." << endl;
    system("Pause");
    return 0;
}

LINKEDLIST

// A class template for holding a linked list.
// The node type is also a class template.
#ifndef RainfallList_H
#define RainfallList_H
#include "Rainfall.h"
//*********************************************
// The ListNode class creates a type used to  *
// store a node of the linked list.           *
//*********************************************
template <class T>
class RainfallListNode
{
public:
    T value;           // Node value
    RainfallListNode<T> *next; // Pointer to the next node
    // Constructor
    RainfallListNode(T nodeValue)
    {
        value = nodeValue;
        next = NULL;
    }
};
//*********************************************
// LinkedList class                           *
//*********************************************
template <class T>
class RainfallList:Rainfall
{
private:
    RainfallListNode<T> *head;   // List head pointer
public:
    // Constructor
    RainfallList()
    {
        head = NULL;
    }
    // Destructor
    ~RainfallList();
    // Linked list operations
    void appendNode(T);
    void insertNode(T);
    void deleteNode(T);
    void displayList() const;
    double getAvg();
    Rainfall getMost();
    Rainfall getLeast();
};

//**************************************************
// appendNode appends a node containing the value  *
// pased into newValue, to the end of the list.    *
//**************************************************
template <class T>
void RainfallList<T>::appendNode(T newValue)
{
    RainfallListNode<T> *newNode;  // To point to a new node
    RainfallListNode<T> *nodePtr;  // To move through the list
    // Allocate a new node and store newValue there.
    newNode = new RainfallListNode<T>(newValue);
    // If there are no nodes in the list
    // make newNode the first node.
    if (!head)
        head = newNode;
    else  // Otherwise, insert newNode at end.
    {
        // Initialize nodePtr to head of list.
        nodePtr = head;
        // Find the last node in the list.
        while (nodePtr->next)
            nodePtr = nodePtr->next;
        // Insert newNode as the last node.
        nodePtr->next = newNode;
    }
}
//**************************************************
// displayList shows the value stored in each node *
// of the linked list pointed to by head.          *
//**************************************************
template <class T>
void RainfallList<T>::displayList() const
{
    RainfallListNode<T> *nodePtr;  // To move through the list
    // Position nodePtr at the head of the list.
    nodePtr = head;
    // While nodePtr points to a node, traverse
    // the list.
    while (nodePtr)
    {
        // Display the value in this node.
        cout << nodePtr->value << endl;
        // Move to the next node.
        nodePtr = nodePtr->next;
    }
}
//**************************************************
// The insertNode function inserts a node with     *
// newValue copied to its value member.            *
//**************************************************
template <class T>
void RainfallList<T>::insertNode(T newValue)
{
    RainfallListNode<T> *newNode;             // A new node
    RainfallListNode<T> *nodePtr;             // To traverse the list
    RainfallListNode<T> *previousNode = NULL; // The previous node
    // Allocate a new node and store newValue there.
    newNode = new RainfallListNode<T>(newValue);
    // If there are no nodes in the list
    // make newNode the first node
    if (!head)
    {
        head = newNode;
        newNode->next = NULL;
    }
    else  // Otherwise, insert newNode
    {
        // Position nodePtr at the head of list.
        nodePtr = head;
        // Initialize previousNode to NULL.
        previousNode = NULL;
        // Skip all nodes whose value is less than newValue.
        while (nodePtr != NULL && nodePtr->value < newValue)
        {
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }
        // If the new node is to be the 1st in the list,
        // insert it before all other nodes.
        if (previousNode == NULL)
        {
            head = newNode;
            newNode->next = nodePtr;
        }
        else  // Otherwise insert after the previous node.
        {
            previousNode->next = newNode;
            newNode->next = nodePtr;
        }
    }
}
//*****************************************************
// The deleteNode function searches for a node        *
// with searchValue as its value. The node, if found, *
// is deleted from the list and from memory.          *
//*****************************************************
template <class T>
void RainfallList<T>::deleteNode(T searchValue)
{
    RainfallListNode<T> *nodePtr;       // To traverse the list
    RainfallListNode<T> *previousNode = nullptr;  // To point to the previous node
    // If the list is empty, do nothing.
    if (!head)
        return;
    // Determine if the first node is the one.
    if (head->value == searchValue)
    {
        nodePtr = head->next;
        delete head;
        head = nodePtr;
    }
    else
    {
        // Initialize nodePtr to head of list
        nodePtr = head;
        // Skip all nodes whose value member is 
        // not equal to num.
        while (nodePtr != NULL && nodePtr->value != searchValue)
        {
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }
        // If nodePtr is not at the end of the list, 
        // link the previous node to the node after
        // nodePtr, then delete nodePtr.
        if (nodePtr)
        {
            previousNode->next = nodePtr->next;
            delete nodePtr;
        }
    }
}
//**************************************************
// Destructor                                      *
// This function deletes every node in the list.   *
//**************************************************
template <class T>
RainfallList<T>::~RainfallList()
{
    RainfallListNode<T> *nodePtr;   // To traverse the list
    RainfallListNode<T> *nextNode;  // To point to the next node
    // Position nodePtr at the head of the list.
    nodePtr = head;
    // While nodePtr is not at the end of the list...
    while (nodePtr != NULL)
    {
        // Save a pointer to the next node.
        nextNode = nodePtr->next;
        // Delete the current node.
        delete nodePtr;
        // Position nodePtr at the next node.
        nodePtr = nextNode;
    }
}
template <class T>
double RainfallList<T>::getAvg()
{
    double avg = 0.0;
    Rainfall obj;
    RainfallListNode<T> *nodePtr;  // To move through the list
    // Position nodePtr at the head of the list.
    nodePtr = head;
    // While nodePtr points to a node, traverse
    // the list.
    while (nodePtr)
    {
        // Display the value in this node.
        //cout << nodePtr->value << endl;
        obj = nodePtr->value;
        avg += obj.getRainfall();
        // Move to the next node.
        nodePtr = nodePtr->next;
    }
    return avg;
}
template <class T>
Rainfall RainfallList<T>::getMost()
{
    //double avg = 0.0;
    Rainfall obj = NULL;
    Rainfall obj2 = NULL;

    RainfallListNode<T> *nodePtr;  // To move through the list
    // Position nodePtr at the head of the list.
    nodePtr = head;
    obj = nodePtr->value;
    // While nodePtr points to a node, traverse
    // the list.
    while (nodePtr)
    {
        // Display the value in this node.
        //cout << nodePtr->value << endl;
        obj2 = nodePtr->value;
        if (obj.getRainfall() < obj2.getRainfall()){
            obj = nodePtr->value;
        }
        // Move to the next node.
        nodePtr = nodePtr->next;
    }
    return obj;
}
template <class T>
Rainfall RainfallList<T>::getLeast()
{
    //double avg = 0.0;
    Rainfall obj = NULL;
    Rainfall obj2 = NULL;
    RainfallListNode<T> *nodePtr;  // To move through the list
    // Position nodePtr at the head of the list.
    nodePtr = head;
    obj = nodePtr->value;
    // While nodePtr points to a node, traverse
    // the list.
    while (nodePtr)
    {
        // Display the value in this node.
        //cout << nodePtr->value << endl;
        obj2 = nodePtr->value;
        if (obj.getRainfall() > obj2.getRainfall()){
            obj = nodePtr->value;
        }
        // Move to the next node.
        nodePtr = nodePtr->next;
    }
    return obj;
}
#endif

降雨类

#ifndef RAINFALL_H
#define RAINFALL_H
#include <iostream>
using namespace std;

//class rainclass;      
//ostream &operator << (ostream & , const Rainfall & );
//istream &operator >> (istream & , Rainfall & );
class Rainfall
{
private:
    int year;
    int month;
    double rainfall;
public:
    Rainfall(void);
    Rainfall(int year, int month, double rainfall);
    void setRain(int year, int month, double rainfall);
    int getYear();
    int getMonth();
    double getRainfall();
    void print();

    // Overloaded operator functions
    Rainfall operator + (const Rainfall &); // Overloaded +
    //Rainfall operator - (const Rainfall &); // Overloaded -
    //Rainfall operator ++ ();                  // Prefix ++
    //Rainfall operator ++ (int);               // Postfix ++
    bool operator > (const Rainfall &);     // Overloaded >
    bool operator < (const Rainfall &);     // Overloaded <
    //bool operator == (const Rainfall &);      // Overloaded ==
    //bool operator != (const Rainfall &);      // Overloaded ==
    // Conversion functions
    //operator double();
    //operator int();
    // Friends
    friend ostream &operator << (ostream &, const Rainfall &);
    //friend istream &operator >> (istream &, Rainfall &);
};
#endif

降雨实现

#include "Rainfall.h"
#include <iostream>
using namespace std;
Rainfall::Rainfall(){
    year = 0;
    month = 0;
    rainfall = 0.0;
}
Rainfall::Rainfall(int tempyear, int tempmonth, double temprainfall){
    year = tempyear;
    month = tempmonth;
    rainfall = temprainfall;
}
void Rainfall::setRain(int tempyear, int tempmonth, double temprainfall){
    year = tempyear;
    month = tempmonth;
    rainfall = temprainfall;
}
int Rainfall::getMonth() {
    return month;
}
int Rainfall::getYear() {
    return year;
}
double Rainfall::getRainfall() {
    return rainfall;
}
void Rainfall::print() {
    cout << "There was " << getRainfall() << " inches of rainfall in " << getMonth() << " of " << getYear() << endl;
}
//**********************************************
// Overloaded binary + operator.               *
//**********************************************
Rainfall Rainfall::operator + (const Rainfall &right)
{
    Rainfall temp;
    //temp.year = year + right.year;
    //temp.month = month + right.month;
    temp.rainfall = rainfall + right.rainfall;
    return temp;
}
//********************************************************
// Overloaded << operator. Gives cout the ability to     *
// directly display FeetInches objects.                  *
//********************************************************
ostream &operator<<(ostream &strm, const Rainfall &obj)
{
    strm << obj.month << "  " << obj.year << "  " << obj.rainfall << "inches" << endl;
    return strm;
}
//************************************************************
// Overloaded > operator. Returns true if the current object *
// is set to a value greater than that of right.             *
//************************************************************
bool Rainfall::operator > (const Rainfall &right)
{
    bool status;
    if (rainfall > right.rainfall)
        status = true;
    //else if (feet == right.feet && inches > right.inches)
        //status = true;
    else
        status = false;
    return status;
}
//************************************************************
// Overloaded < operator. Returns true if the current object *
// is set to a value less than that of right.                *
//************************************************************
bool Rainfall::operator < (const Rainfall &right)
{
    bool status;
    if (rainfall < right.rainfall)
        status = true;
    //else if (feet == right.feet && inches < right.inches)
        //status = true;
    else
        status = false;
    return status;
}

你可以用NULL初始化一个指针,但是将NULL(在后台是一个int)赋值给一个对象(在你的例子中是Rainfall)是没有意义的。

Rainfall most;

就足够了,因为默认情况下,您的rain构造函数已经用零初始化了新对象。