first let me explain my hierarchy :
Person
/ \
Student Employee
\ /
Intern
Each class has an output
function of their own , which prints their data members, and I have to print Person
only once. The problem is that Student
and Employee
are not abstract classes, and people will also make an object of their type, so I can't only call the output function on the Intern
level.
As you will see in the following code, I've managed to solve this, but I think this is ugly and not very polymorphic . I've created an additional output function so it will work for all cases. Is there a better way of achieving this ?
class Person {
string name;
int id;
public:
virtual void output(ostream& out) {
out << name << "," << id;
}
}
Student:
class Student : virtual public Person {
string major;
int year;
public:
virtual void output(ostream& out) {
Person::output(out);
out << "," << major << "," << year;
}
virtual void outputStudOnly(ostream& out) {
out << "," << major << "," << year;
}
};
Employee:
class Employee : virtual public Person{
string jobTitle;
public:
virtual void output(ostream& out) {
Person::output(out);
out << "," << jobTitle;
}
virtual void outputEmpOnly(ostream& out) {
out << "," << jobTitle;
}
};
And Intern :
class Intern : public Student, public Employee {
public:
virtual void output(ostream& out) {
Person::output(out);
Student::outputStudOnly(out);
Employee::outputEmpOnly(out);
}
};
That what template method is for. Here is how I would write this code:
class Person {
string name;
int id;
public:
void output(ostream& out) {
out << name << "," << id;
output_impl(out);
}
private:
virtual void output_impl(ostream& ) {}
};
class Student : virtual public Person {
string major;
int year;
private:
virtual void output_impl(ostream& out) {
out << "," << major << "," << year;
}
};
class Employee : virtual public Person {
string jobTitle;
private:
virtual void output_impl(ostream& out) {
out << "," << jobTitle;
}
};
class Intern : public Student, public Employee {
private:
virtual void output_impl(ostream& out) {
Student::output_impl(out);
Employee::output_impl(out);
}
};
And than you call output
on the object.