Background Info
I've been programming in Java for a while, and I've only switched over to C++ just a few months ago, so I apologize if the answer is just something silly that I missed! Now that that's all been said, it is time for the issue at hand! I am developing a basic text-based game engine, and I recently ran into an interestingly specific and unlikely problem. I tried testing it out on a smaller scale in the program below, and decided to just show that (as opposed to my actual game code), as to not choke the screen, and make the issue less convoluted. The problem modeled below mirrors the problem with my actual code, just without the fluffy distractors.
The Problem
Essentially the problem is one of polymorphism. I want to overload the output operator "<<" to serve as a display function that is unique for each object in the hierarchy. The issue is that when I call this operator from a list which stores these hierarchy members, they lose their identity and call the output operator of the base class. Normally, one would solve this by replacing the operator overloads with a simple display method, marking the display method virtual, and moving on with their happy day. I don't particularly mind making that alteration to the code, but now I'm just plain curious. Is there a way to overload operators in a hierarchy that results in what I'm going for here?
The [Example] Code
#include <vector>
#include <iostream>
#include <string>
using namespace std;
class Polygon {
friend ostream& operator<<(ostream& os, const Polygon& p);
public:
private:
};
class Rectangle : public Polygon {
friend ostream& operator<<(ostream& os, const Rectangle& r);
public:
private:
};
class Square : public Rectangle {
friend ostream& operator<<(ostream& os, const Square& s);
public:
private:
};
ostream& operator<<(ostream& os, const Polygon& p) {
os << "Polygon!" << endl;
return os;
}
ostream& operator<<(ostream& os, const Rectangle& r) {
os << "Rectangle!" << endl;
return os;
}
ostream& operator<<(ostream& os, const Square& s) {
os << "Square!" << endl;
return os;
}
int main() {
vector<Polygon*> listOfPoly;
listOfPoly.push_back(new Polygon());
listOfPoly.push_back(new Rectangle());
listOfPoly.push_back(new Square());
for(Polygon* p : listOfPoly) {
cout << *p;
}
}
Output for [Example] Code
Polygon!
Polygon!
Polygon!
Desired output for [Example] Code
Polygon!
Rectangle!
Square!
operator<<
is a friend (and not a member), the short answer is no, you need an internal display operator that's marked virtual – CrymotherapylistOfPoly.push_back(new Polygon());...
Prefer to use smart pointers instead. – JatSquare
IS-ARectangle
IS-APolygon
? Seriously? Please read up on the Liskov substitution principle. – Bolitho