#include #include /* below tweak needs to know wbout this class */ template class Polygon; /* convine the compiler that overloaded operators are templates themselves before * we reach the declaration of the class */ template std::ostream& operator<<(std::ostream &, const Polygon &); template class Polygon { public: /* notice the <> after function name, we're letting g++ know this is a template */ friend std::ostream& operator<<<>(std::ostream &, const Polygon &); /* pure virtual, subclass must DEFINE it. otherwise that subclass itself * will remain abstract and won't be able to be instantiated */ virtual T area(void) = 0; T getWidth(void) { this->width; } T getHeight(void) { this->height; } protected: T width, height; std::string type; /* name of polygon */ }; template class Triangle : public Polygon { public: Triangle() { this->width = 0; this->height = 0; this->type = std::string("triangle"); } Triangle(int b, int h) { this->width = b; this->height = h; /* this keyword has to be used? */ this->type = std::string("triangle"); } virtual T area(void) { return (this->width * this->height) / 2; } }; template std::ostream& operator<<(std::ostream& stream, const Polygon& p) { stream << p.type << " dimensions, width: " << p.width << ", height: " << p.height << ", area: "<< const_cast *>(&p)->area(); /* lol at the cast! */ return stream; } int main(int argc, char *argv[]) { Triangle tri(6, 4); std::cout << tri << std::endl; return 0; }