0

我正在尝试使用 Student 类并将其声明为列表类型。我可以推回但不更改 List.h 或 Node.h 如何打印 list2 中的数据?List..h 中给定的 print() 函数不起作用:(

节点.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 */

列表.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

学生.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);
 }

主文件

 #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;

 }
4

3 回答 3

1

<< 运算符必须为您的 Student 类定义。引用 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;
    }
  }

因此,在您的 Student 类中,您需要实现 operator<<(ostream &out);

做朋友(朋友很有趣!):

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/

于 2013-07-03T17:11:20.370 回答
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虚拟中创建析构函数,除非您计划将其作为其他类的基类。

于 2013-07-03T17:07:00.447 回答
0

打印功能需要在您的学生班级上定义一个运算符 << ,但事实并非如此

所以定义一个学生将如何通过 << 显示,它应该可以工作!

于 2013-07-03T17:08:07.093 回答