2012-03-25 32 views
1

我有一類學生存儲在我的cpp文件中。我遇到的問題是打印出實際的學生對象。我嘗試了所有我能想到的,我得到的只是指針的地址或編譯錯誤。我在我的學生課中有一個名爲display的方法,以我想要的格式輸出所有信息。如何從C++中的一組對象指針打印?

這是我到目前爲止。

.cpp文件

#include "Name.h" 
#include "Student.h" 
#include<iostream> 
#include<string> 
#include<set> 
using namespace std; 

int main() 
{ 
    Student s1; 
    set<Student *> s; 
    while(cin>>s1) 
    { 
     s.insert(new Student(s1)); 
    } 
    for(set<Student *>::const_iterator it = s.begin(); it != s.end(); ++it) 
    { 
     &(*it).display(cout); 
    } 
} 

Student.h

#ifndef STUDENT_H 
#define STUDENT_H 
#include<string> 
#include<iostream> 
#include<map> 
#include "Name.h" 
typedef std::map<std::string, int> GradeMap; 

class Student { 
public: 
    Student(const std::string id="", const Name& name = Name(),const GradeMap & grades = GradeMap()):id_(id),name_(name),grades_(grades){} 
    Student(const Student& s):id_(s.id_),name_(s.name_),grades_(s.grades_){} 
    virtual ~Student(){} 
    friend std::istream& operator>>(std::istream& is, Student& s); 

    virtual void display(std::ostream& os) const{ 
     os << "ID: " << id_ <<std::endl<< "Name: " << name_ << std::endl; 

     for(std::map<std::string, int>::const_iterator it = grades_.begin(); it != grades_.end(); ++it) 
      os<<it->first<<' '<<it->second<<std::endl; 
    } 

private: 
    std::string id_; 
    Name name_; 
    GradeMap grades_; 

}; 

inline std::istream& operator>>(std::istream& is, Student& s) 
{ 
    std::string id; 
    std::string key; 
    int grade; 
    int count = 0; 
    Name name; 

    if(is>>id>>name>>count){ 
     s.id_ = id; 
     s.name_ = name; 
    } 
    else { 
     is.setstate(std::ios_base::failbit); 
    } 


    for(int i = 0; i < count; i++) 
    { 
     if(is>>key>>grade) 
     { 
      s.grades_[key] = grade; 
     } 
    } 
    return is; 
} 
#endif 

Name.h

#ifndef NAME_H 
#define NAME_H 
#include <string> 
#include <iostream> 
class Name{ 
    public: 
     explicit Name(const std::string& first = "",const std:: string& last = ""):first_(first),last_(last){} 
     friend std::ostream& operator<<(std::ostream&, const Name&); 
     friend std::istream& operator>>(std::istream&, Name&); 
private: 
     std::string first_; 
     std::string last_; 
}; 

inline std::ostream& operator<<(std::ostream& os, const Name& n){ 
    return os << n.first_<< " " << n.last_; 
} 
inline std::istream& operator>>(std::istream& is, Name& n){ 
    std::string first,last; 
    if(is >> first >> last){ 
     n.first_ = first; 
     n.last_ = last; 
    } 
    else 
     is.setstate(std::ios_base::failbit); 
    return is; 
} 
#endif 

也在這裏是我使用來測試這個

111111111 
john smith 
3 
comp2510 25 
eng2525 60 
bio3512 45 
222222222 
jane doe 
2 
elex1510 90 
comp2510 85 
01文件

該文件是這樣組織的。學生的ID首先是他們的名字,然後是他們接受的課程數量,然後是那些課程的數量加上他們在該課程中的成績。

我的問題是如何打印出實際的學生對象?

+3

請注意,您的代碼泄漏內存。 – 2012-03-25 19:56:35

+0

每當你發現自己使用指針或「新」,你應該非常,非常擔心,並確定你明白你爲什麼這樣做,爲什麼你沒有做得更好。 – 2012-03-25 19:59:03

+0

你的權利,我忘了我需要釋放內存 – user798774 2012-03-25 20:07:08

回答

4

for循環:

for(set<Student *>::const_iterator it = s.begin(); it != s.end(); ++it) 
{ 
    &(*it).display(cout); 
} 

(*it)Student*

(*it)->display(cout); 
+0

謝謝我沒有想到之前 – user798774 2012-03-25 20:05:41

1

迭代器的行爲就像一個指針到實際的set元素,所以提領該迭代給你設定的元素。該元素本身就是一個指向Student對象的指針。所以,你需要取消引用兩次:

(**it).display(cout); 

哪家好寫爲:

(*it)->display(cout); 

更重要的是,重載<<運營商以類似的方式來>>,你可以寫:

cout << (**it); 

(圓括號只是爲了清楚起見)


更好的是,根本不用擔心指針,並且將s聲明爲set<Student>。當然,會有更多的複製,但你會停止泄漏內存,並得到更清潔,更簡單,更安全,更可維護的代碼。 (您將需要<超負荷來比較Student s雖然。)

+0

<<甚至是兩個班輪: std :: ostream&operator <<(std :: ostream&o,Student s){ s.display(o); return o; } – 2012-03-25 20:02:22

0
#include <string> 
#include <iostream> 

class Student 
{ 
    std::string m_name; 

public: 
    Student(const std::string& name) : 
    m_name(name) 
    { 
    } 

    std::ostream& display(std::ostream& os) const 
    { 
     return os << m_name; 
    } 

    bool operator<(const Student& other) const 
    { 
     return m_name < other.m_name; 
    } 
}; 

Student定義operator<<

std::ostream& operator<<(std::ostream& os, const Student& student) 
{ 
    return student.display(os); 
} 

使用它:

#include <set> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    std::set<Student> students; 

    students.insert(Student("Alan")); 
    students.insert(Student("Rudy")); 

    std::copy(students.begin(), students.end(), 
       std::ostream_iterator<Student>(std::cout, ", ")); 

    return 0; 
} 

輸出:

Alan, Rudy,