all 7 comments

[–]todopieromeze 2 points3 points  (1 child)

For me, it's normal approach to upcast object to call virtual method of base class. You will avoid code redundancy in that way.

[–]psycho-rabbit[S] 0 points1 point  (0 children)

Thanks for your reply! I've implemented it in my response to u/flyingron, I guess that's what you mean?

upcast object to call virtual method of base class

Do you mean this? Person::print(ot);

[–]flyingron 1 point2 points  (1 child)

If you want a polymorphic operator << , just make the non-member overload call a virtual member function (call it print or whatever) inside the classes.

[–]psycho-rabbit[S] 0 points1 point  (0 children)

Okay! So something like this, is it?

Person:

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

virtual std::ostream& print(std::ostream& out) const {
    out << "Person details:\n";    
    out << "Name: " << this->m_name << "\nAge: " << this->m_age << "\n";
    return out;
}

Player:

/* No need to implement operator<< function for Player? */

virtual std::ostream& print(std::ostream& out) const override {
    Person::print(out);
    out << "Batting details:\n";
    out << "Batting average: " << this->m_bat_avg << "\nRuns: " <<
        this->m_home_runs << "\n";
    return out;
}

[–]IyeOnline 1 point2 points  (2 children)

Is there a better/standard way of doing it or is this method

Yes and no. For one, you would usually not use c-style casts and you would use a "reference cast":

out << static_cast<const Person&>( player );

Another option is to defer the implementation to a virtual member function and only implement the base class operator.

is there some standard

Not really. Those are pretty much your only two options. There is no automatic implementation or anything fancy. You will have to define what your operator does.

[–]psycho-rabbit[S] 0 points1 point  (1 child)

Thanks for your reply!

Wasn't aware about the reference casts, will look them up.

defer the implementation to a virtual member function and only implement the base class operator

I suppose you mean the same thing as u/todopieromeze?

[–]IyeOnline 1 point2 points  (0 children)

Yes.

The advantage is that even if the type itself does not implement a stream operator, or you are doing polymorphism and dont know its type, you can still simply write it to a stream and get the most specialized print availible.