2016-11-09 9 views
1

名前と番号の2つのフィールドを持つPersonクラスがあるとします。 Class StudentはPersonを継承し、averageGradeという別のフィールドを追加します。C++多形印刷

PersonとStudentの演算子「< <」を定義し、Studentオブジェクトも含むPersonの配列を持たせたいと考えています。私は生徒になる配列から要素を出力したいとき、Personのためのものではなく、Studentが呼び出されることに特有の演算子 "< <"の定義が必要です。

これを行うにはどうすればよいですか?

person.h:

#pragma once 
#include <iostream> 
#include <string> 
using namespace std; 


class Person 
{ 
    private: 
     string name; 
     int number; 
    public: 
     Person(); 
     Person(string,int); 

     friend ostream& operator<<(ostream& os, const Person& person); 
}; 

person.cpp:

#include "person.h" 

Person::Person() : Person("defaultName", 0) 
{ 
} 

Person::Person(string name, int number) 
{ 
    this->name = name; 
    this->number = number; 
} 

ostream& operator<<(ostream& os, const Person& person) 
{ 
    os << "Name: " << person.name << endl; 
    os << "Number: " << person.number; 

    return os; 
} 

student.h:

#pragma once 
#include "person.h" 

class Student : public Person 
{ 
    private: 
    double averageGrade; 
    public: 
    Student(); 
    Student(string, int, double); 

    friend ostream& operator<<(ostream& os, const Student& student); 
}; 

student.cpp:

#include "student.h" 
Student::Student() : Person() 
{ 
    this->averageGrade = 5.0; 
} 

Student::Student(string name, int number, double avgGrade) : Person(name, number) 
{ 
    this->averageGrade = avgGrade; 
} 

ostream& operator<<(ostream& os, const Student& student) 
{ 
    os << (Person) student << endl; 
    os << "Average grade: " << student.averageGrade; 

    return os; 
} 

main.cpp:

#include "student.h" 

int main() 
{ 

    Person people[10]; 
    people[0] = Person("Tom", 1); 
    people[1] = Student("Greg", 6, 5.74); 
    cout << people[0] << endl; 
    cout << people[1] << endl; // prints only the name and number, without the grade 


    return 0; 
} 
+0

実行時の多型性については、仮想を見ることができます。 – themagicalyang

+4

基本クラスに 'std :: ostream&print(std :: ostream&os)'のような['virtual'](http://en.cppreference.com/w/cpp/language/virtual)関数を与え、ベースクラスのoperator << 'を呼び出すだけです。 '<<'自身を 'virtual'にすることはできません。メンバー関数ではないからです(ストリームは最初の引数でなければなりません)。 – BoBTFish

+1

異なるタイプの人を1つの配列にまとめたい場合は、(スマートな)ポインタを格納する必要があります。今あなたがしているのは "スライス"と呼ばれています: 'people [1] = Student(" Greg "、6、5.74);' Person'(*ではなく 'Student'!右側の「学生」からのフィールド。 –

答えて

3

アプローチは簡単に見えます。各クラスの

例えば

virtual std::ostream & out(std::ostream &); 

ようなパブリックまたは保護された仮想関数を定義し、

friend std::ostream & operator <<(std::ostream &os, const Person &person) 
{ 
    return person.out(os); 
} 

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

またはだけ持っているように、出力演算子を書きます最初の演算子。

PersonとStudentsのタイプのオブジェクトを一緒に格納する配列を宣言しないことを考慮してください。

+0

私のコードは現在どのようになっているのでしょうか?私は元の投稿を編集しました。 –

+1

@ Mr.Nicky私が書いたように、タイプPersonの配列を定義せず、そこにタイプStudentのオブジェクトを格納することはできません。 –