是什么导致指针重置?

时间:2013-02-15 22:25:56

标签: c++ inheritance linked-list

我正在开发一个类的程序,它创建一个模板化类的链接列表,以保存有关学生,教师和管理的信息。学生,管理员和教师都继承了一个名为Person的类。我的问题出在我的list类和我的RecordsOffice类中,当程序离开addToList函数时,头指针重置它的数据,我看不到我刚刚添加到列表中的内容。

这是TemplatedList类

//Author:Angelo Todaro
//TemplatedList.h
//Header file for the TemplatedList class

#include "person.h"
#include "student.h"
#include "administrator.h"
#include "faculty.h"

using namespace std;
#ifndef TemplatedList_H
#define TemplatedList_H

template<class T> 
struct Node{
    T *data;
    Node *next;
};


template <class T, typename T2>
class TemplatedList{
public:
    /*Default Constructor
    *Constructs an object of the TemplatedList class*/
    TemplatedList();

    /*Default Destructor
    *Destructs an object of the TemplatedList class*/
    ~TemplatedList();

    /*Accessor Method for head node
    *Provides user access to the value of the head node*/
    T getHead() const;

    /*Modifier Method for head node
    *Provides the user access to change the value of the head node*/
    void setHead(T *newHead);

    /*addToList
    *Adds a Student to the list*/
    void addToList(T *newStudent);

    /*deleteFromList
    *Deletes a Student from the list*/
    void deleteFromList(T2 number);

    /*printStudent
    *prints the information of the specified student*/
    void printSingle(T2 number);

    /*printList
    *prints the entire list of students*/
    void printList();

private:
    T *head;
};

#endif


/*Default Constructor
*Constructs an object of the TemplatedList class*/
template <class T, typename T2>
TemplatedList<T,T2>::TemplatedList(){
    head = new T;
    head->next=NULL;
    head->data=NULL;
}

/*Default Destructor
*Destructs an object of the TemplatedList class*/
template <class T, typename T2>
TemplatedList<T,T2>::~TemplatedList(){
    delete head;
    head=NULL;
}

/*Accessor Method for head node
*Provides user access to the value of the head node*/
template <class T, typename T2>
T TemplatedList<T,T2>::getHead() const{
    return head;
}

/*Modifier Method for head node
*Provides the user access to change the value of the head node*/
template <class T, typename T2>
void TemplatedList<T,T2>::setHead(T *newHead){
    head=newHead;
}

/*addToList
*Adds a Person to the list*/
template <class T, typename T2>
void TemplatedList<T,T2>::addToList(T *newPerson){
    T *curr=head;
    T *prev=curr;
    cout << "Adding ";
    newPerson->data->print();
    cout << endl;
    if(head->next==NULL && head->data==NULL)//if list has not been initialized
    {

        head->data=newPerson->data;
        head->data->print();
        head->next=NULL;
    }
    //if new Person's M Number is less than the head's MNumber
    else if(newPerson->data->getMNumber()<head->data->getMNumber())
    {
        newPerson->next=head->next;
        head = newPerson;
    }
    else //all other cases
    {
        while(curr!=NULL && 
                newPerson->data->getMNumber()>curr->data->getMNumber())
        {
            prev=curr;
            curr=curr->next;
        }
            newPerson->next=curr;
            prev->next= newPerson;
        if(curr==NULL)
            newPerson->next=NULL;
    }

}

/*deleteFromList
*Deletes a Person from the list*/
template <class T, typename T2>
void TemplatedList<T,T2>::deleteFromList(T2 number){
    T *curr=head;
    T *prev=head;
    if(head==NULL||head->next==NULL){
        cout << "Can not delete Person (M" << number << "), NOT found!" << endl;
    }
    //if first Person is equal to the selected one to delete
    else if(curr->data->getMNumber()==number)
    {
        prev->next=curr->next;
        delete curr;
        curr=NULL;
    }
    else
    {
        while(curr!=NULL &&
            curr->data->getMNumber()!=number)
        {
            prev=curr;
            curr=curr->next;
        }
        if(curr!=NULL)//If not at end of list
        {
            prev->next=curr->next;
            delete curr;
            curr = NULL;

        }
        else//there is no listing
        {
            cout << "Can not delete Person (M" << number << "), NOT found!" << endl;
        }
    }
    cout << endl;
}

/*printPerson
*prints the information of the specified Person*/
template <class T, typename T2>
void TemplatedList<T,T2>::printSingle(T2 number){
    T *curr=head;
    T *prev=curr;
    while(curr!=NULL && curr->data->getMNumber()!=number)
    {
        prev=curr;
        curr=curr->next;
    }
    if(curr!=NULL)//if match is found
    {
        curr->data->print();
    }
    else//there is no listing
    {
        cout << "Can not print person (M" << number << "), NOT found!" << endl << endl;
    }

}

/*printList
*prints the entire list of Persons*/
template <class T, typename T2>
void TemplatedList<T,T2>::printList(){
    T *curr=head;
    T *prev=curr;
    while(curr!=NULL)
    {
        curr->data->print();
        prev=curr;
        curr=curr->next;
    }
    cout << endl;
}

这是RecordsOffice类的实现

//Author:Angelo Todaro
//recordsOffice.cpp
//Implementation file for the RecordsOffice class

#include <iostream>
#include <fstream>
#include <cassert>
#include "recordsOffice.h"


/*Default Constructor
Creates an object of the RecordsOffice class*/
RecordsOffice::RecordsOffice(){

}

/*Default Destructor
*Destructs an object of the RecordsOffice class*/
RecordsOffice::~RecordsOffice(){


}

/*Accessor Method for List of Persons
*Provides the user with a way to retrieve m_List*/
TemplatedList<Node<Person>,int> RecordsOffice::getList() const{
    return m_List;
}

/*Modifier Method for List of Persons
*provides a way for the user to modify m_List*/
void RecordsOffice::setList(TemplatedList<Node<Person>,int> newList){
    m_List = newList;
}



/*parseCommands
*parses the command entered and calls appropriate function*/
void RecordsOffice::parseCommands(string fileName){
    ifstream infile;//create new file stream
    infile.open(fileName);//opens file
    assert(infile);//check for valid file
    char command;//stores the value of the current command

    while(infile >> command)
    {
        if(command=='A')
        {
            string name, email, title;//temporary strings  to hold values of Person
            int mnumber;//temporary ints to hold values of Person
            infile >> name >> mnumber >> email >> title;
            Administrator admin = Administrator(name,mnumber,email,title);
            Node<Person> *newper = new Node<Person>;
            newper->data=&admin;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='F')
        {

            string name, email, department;//temporary strings  to hold values of Person
            int mnumber;//temporary ints to hold values of Person
            bool tenured;
            infile >> name >> mnumber >> email >> department >> tenured;
            Faculty fac= Faculty(name,mnumber,email,tenured,department);
            Node<Person> *newper = new Node<Person>;
            newper->data=&fac;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='S')
        {
            string name, email, major;//temporary strings  to hold values of Person
            int mnumber, year;//temporary ints to hold values of Person
            infile >> name >> mnumber >> email >> year >> major;
            Student stu= Student(name,mnumber,email,year,major);
            Node<Person> *newper = new Node<Person>;
            newper->data=&stu;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='D')
        {
                int mnum;//int to store mnumber
                infile >> mnum;
                cout << "Deleting M" << mnum << endl;
                m_List.deleteFromList(mnum);
        }
        else if(command=='P')
        {
                int mnum;//int to store mnumber
                infile >> mnum;
                cout << "Printing M" << mnum << endl;
                m_List.printSingle(mnum);
        }
        else if(command=='L')
        {
                cout << "Listing all Persons" << endl;
                m_List.printList();
        }

    }
}

程序正在读取的文件包含

A   Doe 4444    jdoe3@mtsu.com  President
L
P   4444
F   Johnson 2222    cjLittle@mtsu.com   English 0
P   2222
S   Reed    9999    reed@mtsu.com   1   History
P   9999
L
D   9999
D   2222
D   4444

1 个答案:

答案 0 :(得分:1)

newper->data总是指向局部变量,当局部变量超出范围时,它们实际上被释放,newper->data不再指向有效数据。您需要使用new的动态存储时长。

Administrator admin = Administrator(name,mnumber,email,title);
newper->data=&admin;

Faculty fac= Faculty(name,mnumber,email,tenured,department);
newper->data=&fac;

Student stu= Student(name,mnumber,email,year,major);
newper->data=&stu;

尝试:

Person *admin = new Administrator(name,mnumber,email,title);
newper->data = admin;

Person *fac = new Faculty(name,mnumber,email,tenured,department);
newper->data = fac;

Person * stu = new Student(name,mnumber,email,year,major);
newper->data=stu;