2013-07-03 83 views
0

我想使用一個類的學生,並將其聲明爲一個列表類型。我可以推遲但不改變List.h或Node.h我怎麼能打印list2中的數據?內List..h給出的print()函數不工作:(C++列表類作爲學生類型

Node.h

#ifndef NODE_H 
#define NODE_H 
#include <string> 
#include <iostream> 
using namespace std; 
template <typename T> 
class Node { 
private: 
    T data; 
    Node<T>* next; 
public: 
    Node(T); 
    virtual ~Node(); // base class destructor must be virtual 

    template <typename U> friend class List; 
}; 
template <typename T> 
Node<T>::Node(T d) { 
    data = d; 
    next = NULL; 
} 
template <typename T> 
Node<T>::~Node() { 
} 
#endif /* STRNODE_H */ 

List.h

#ifndef LIST_H 
#define LIST_H 
#include "Node.h" 

// Singly linked list 
template <typename T> 
class List { 
private: 
    Node<T>* head; // pointer to the first node 
    Node<T>* tail; // pointer to the last node 
    int count; // number of nodes in the list 
public: 
    class OutOfRangeException{ }; // empty inner class for exception handling 
    List(); 
    virtual ~List(); 
    void push_back(T item); 
    void insert(int index, T item); 
    void remove(int index); 
    int indexOf(T item); 
    T get(int position); // OutOfRangeException is generated 
    bool isEmpty(); 
    int size(); 
    void print(); 
    }; 
template <typename T> 
List<T>::List() { 
head = tail = NULL; 
    count = 0; 
} 
template <typename T> 
List<T>::~List() { 
Node<T>* discard; 
while (head != 0) { 
discard = head; 
head = head->next; 
delete discard; 
} 
} 

// append an item at the end of the StrList 
template <typename T> 
void List<T>::push_back(T item) { 
try { 
Node<T>* newNode = new Node<T>(item); 
if (head == 0) { 
    head = tail = newNode; 
    } else { 
    tail->next = newNode; 
    tail = newNode; 
    } 
    ++count; 
    } catch (bad_alloc &e) { 
    cout << "memory allocation exception: " << e.what() << endl; 
exit(1); 
} 
} 

// insert an item at the specified index 
template <typename T> 
void List<T>::insert(int index, T item) { 
try { 
if (index < 0 || index > count) // push_back() if index == count 
    throw OutOfRangeException(); 

    Node<T>* newNode = new Node<T>(item); 
    if (head == 0) { // empty 
    head = tail = newNode; 
    } else if (index == 0) { // at the start 
    newNode->next = head; 
    head = newNode; 
    } else if (index == count) { // at the end 
    tail->next = newNode; 
    tail = newNode; 
    } else { // insert in the middle 
    Node<T>* prevNode; 
    Node<T>* currNode = head; 
    for (int i = 0; i < index; i++) { 
    prevNode = currNode; 
    currNode = currNode->next; 
    } 
    // insert between 'prevNode' and 'currNode' 
    prevNode->next = newNode; 
    newNode->next = currNode; 
} 
    ++count; 

} catch (bad_alloc &e) { 
cout << "memory allocation exception: " << e.what() << endl; 
    exit(1); 
} 
} 

// is the StrList empty? 
    template <typename T> 
    bool List<T>::isEmpty() { 
    return count == 0; 
    } 

    // remove the item at specified index 
    template <typename T> 
    void List<T>::remove(int index) { 
    if (index < 0 || index >= count) 
    throw OutOfRangeException(); 

    if (index == 0) { // at the start 
    Node<T>* discard = head; 
    head = head->next; 
    delete discard; 
    } else { 
    Node<T>* prevNode; 
    Node<T>* currNode = head; 
    for (int i = 0; i < index; i++) { 
    prevNode = currNode; 
    currNode = currNode->next; 
    } 
    // remove 'currNode' 
    prevNode->next = currNode->next; // bypass 
    delete currNode; 

    if (index == count - 1) // last node was removed. Update 'tail' 
    tail = prevNode; 
    } 
    --count; 
    if (count == 0) 
    tail = NULL; 
    } 

// retrieve the item at the given position of the StrList. position starts from 0. 
    // throws OutOfRangeException if invalid position value is given. 
    template <typename T> 
T List<T>::get(int position) { 
    if (position < 0 || position >= count) 
    throw OutOfRangeException(); 

    int loc = 0; 
    Node<T>* curr = head; 
    while (loc < position) { 
    ++loc; 
    curr = curr->next; 
    } 
    return curr->data; 
    } 

    // Requirement: 
    // != operator of <class T> is used 
    template <typename T> 
int List<T>::indexOf(T item) { 
    if (head == 0) { 
    return -1; // not found 
    } else { 
    int index = 0; 
    Node<T>* currNode = head; 
    while (currNode->data != item && currNode != NULL) { 
    currNode = currNode->next; 
    ++index; 
    } 
    if (currNode == NULL) // not found thru the end 
    return -1; 
    else 
    return index; 
} 
} 

    // number of nodes in the StrList 
    template <typename T> 
    int List<T>::size() { 
    return count; 
    } 

// Requirement: 
// << operator for <class T> is used. 
    template <typename T> 
void List<T>::print() { 
    cout << "*** StrList contents ***" << endl; 
    for (int i = 0; i < count; i++) { 
    cout << i << ": " << get(i) << endl; 
    } 
    } 
#endif 

Student.h

#include "List.h" 

class Student { 
private: 
string name; 
int id; 
public: 
Student(); 
Student(string a); 
virtual ~Student(); 
friend ostream& operator<<(ostream &os, const Student& p); 
bool operator!=(const Student &p) const; 
bool operator==(const Student &p) const; 
}; 
Student::Student() { 
} 
Student::Student(string a) { 
name = a; 

} 
Student::~Student() { 

} 
ostream& operator<<(ostream &os, const Student& p) { 
return os << p.name; 
} 
bool Student::operator==(const Student &p) const { 
// Compare the values, and return a bool result. 
if (name == p.name) 
    return true; 
else 
return false; 
} 
bool Student::operator!=(const Student &p) const { 
return !(*this == p); 
} 

main.cpp

#include <iostream> 
using namespace std; 

#include "Student.h" 

int main() { 

    cout << "\n*** StrList Test ***" << endl; 

List<string> list; 
list.push_back("zero"); 
list.push_back("one"); 
list.push_back("two"); 
list.push_back("three"); 
list.push_back("four"); 
list.push_back("five"); 
list.print(); 

    list.insert(1, "inserted at position 1"); 
    list.insert(0, "inserted at position 0"); 
    list.insert(4, "inserted at position 4"); 
    list.print(); 

    cout << "removing at indexes 3, 0" << endl; 
    list.remove(3); 
    list.remove(0); 
list.print(); 

list.insert(2, "inserted at position 2"); 
list.print(); 

    cout << "five is at index " << list.indexOf("five") << endl; 
    cout << "two is at index " << list.indexOf("two") << endl; 

    //Test for my Student class implementation 
    // Student<string> st1; //Create new student Ryan Martin with id of 1 
    List<Student> list2; 
    Student stu("Ryan Martin"); 
    list2.push_back(stu); 
    //list2.print(); 
    //list2.push_back("Ryan"); 
    //list2.PrintStudents(); //Test that the Student class successfully stored and can   access 
    return 0; 

} 

回答

1

如果我理解正確的話,那麼你要定義operator<<爲您的學生類,比如,你可以這樣做:但是

friend std::ostream & operator<<(std::ostream & os, const Student & s) 
{ 
    return os << s.name << " " << s.id << std::endl; 
} 

請注意,我沒有測試過此代碼,我沒有閱讀您發佈的所有代碼段, ,這樣我可能會錯誤地理解你。

編輯: 所以與Visual Studio試圖出來後,你的完整版學生類應該是這樣的:

#include "List.h" 

class Student { 
    private: 
    string name; 
    int id; 
    public: 
    Student(); 
    Student(string a); 
    virtual ~Student(); 

    friend std::ostream & operator<<(std::ostream & os, const Student & s) 
    { 
     return os << s.name << " " << s.id << std::endl; 
    } 
}; 

Student::Student() { 
} 

Student::Student(string a) { 
name = a; 
} 
Student::~Student() { 
} 

而且不是說你沒有讓析構函數中Student虛擬除非你打算把它作爲其他類的基類。

0

打印功能需要運營商< <要對你的學生類中定義的,它不是這種情況

這樣定義一個學生怎麼會通過顯示< <,它應該工作!

+0

所以現在確定我有工作我的最後一個問題是實現一個=操作!所以如果有兩個同名的學生,他們是相同的。我怎樣才能測試它與我有什麼: – Ryan

+0

添加布爾運算符==或!=或兩者(const Stend&refS){返回名稱== refS.name && ID == refS.ID; } ....只是想用||當植入不相等的操作員...對不起,如果我不遵循代碼的寫作風格,我的手機相當有限。 – alexbuisson

+0

太棒了!我得到它的工作,感謝您的幫助。 – Ryan

1

< <運算符必須爲您的學生類定義。引述List.h:

// Requirement: 
// << operator for <class T> is used. 
    template <typename T> 
void List<T>::print() { 
    cout << "*** StrList contents ***" << endl; 
    for (int i = 0; i < count; i++) { 
    cout << i << ": " << get(i) << endl; 
    } 
    } 

所以在你的學生類,你需要實現運營商< <(ostream的&出);

做它作爲一個朋友(朋友的樂趣!):

friend std::ostream& operator<< (std::ostream &out, const Student &stu) 
{ 
    return out << stu.name << " id: " << stu.id << std::endl; 
} 

這裏是一個很好的參考: http://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/