Let's say that we have class Person with two fields - name and number. Class Student inherits Person and adds another field called averageGrade.
I've defined the operator "<<" for Person and Student and want to be able to have an array of Person, which would also contain Student objects as well. When I want to print an element from the array which happens to be a Student, I want the definition for the operator "<<" that's specific for Student to be called, not the one for Person.
How does one go about doing that?
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;
}
An approach can look simple.
In each class define for example a public or protected virtual function like
virtual std::ostream & out( std::ostream & );
and then write the output operator like
friend std::ostream & operator <<( std::ostream &os, const Person &person )
{
return person.out( os );
}
and
friend std::ostream & operator <<( std::ostream &os, const Student &student )
{
return student.out( os );
}
or have only the first operator.
Take into account that you may not declare an array that will store objects of type Person and Students together.