2013-02-15 71 views
-2

我正在开发一个课程程序,它创建一个模板类的链接列表,以保存关于学生,教师和管理的信息。学生,管理员和学院都会继承一个名为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 [email protected] President 
L 
P 4444 
F Johnson 2222 [email protected] English 0 
P 2222 
S Reed 9999 [email protected] 1 History 
P 9999 
L 
D 9999 
D 2222 
D 4444 
+0

您是否能以内存断点调试? – Synxis 2013-02-15 22:29:21

+0

基本上我得到的是,它成功地将它添加到列表中,因为它在我说head-> data = newPerson-> data;之后从头变量中输出信息。我相当确定问题在于当我离开addToList函数时,由于当我进入printList函数时head-> data全部被重置。 – todaroa 2013-02-15 22:31:36

+0

管理员,学院,学生在Stack中声明,并且您正在获取这些地址。当你做m_List.addToList(newper); newper包含newper-> data =&something-on-stack,newper->数据一旦从呼叫返回就会失效。您需要新的管理员,教职员等将其保存在内存中。它仍然可能不是你的问题的原因,但你*会*在某点100%看到这一点。 – Grzegorz 2013-02-15 22:32:07

回答

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; 
+0

所有这一切都会导致一个错误,因为没有从Faculty到Faculty的合适的转换函数* 编辑:我在调用构造函数之前添加了new,它解决了问题。 – todaroa 2013-02-15 22:41:37

+0

如果'Administrator,Faculty,Student'都是从person继承的,则需要使用'Person'指针指向派生类型。多晶现象会起作用,不是吗? – billz 2013-02-15 22:45:55