// Drawable shapes // // Handling a collection of polymorphic objects in a conventional OOP style: // an abstract base class (interface) overridden/implemented in // concrete classes. // // $Id: Shapes-oop.cc,v 1.2 2003/01/27 21:29:49 oleg Exp oleg $ #include using std::cerr; using std::endl; // An Abstract Base Class (interface) class Shape { public: virtual void draw(void) = 0; virtual void offset_by(const float x, const float y) = 0; virtual void set_dim(const float width, const float height) = 0; }; // This is supposed to be a list of shapes to draw // For simplicity, we'll hold three shapes only class Shapes { Shape *s1, *s2, *s3; public: Shapes(Shape * const _s1, Shape * const _s2, Shape * const _s3) : s1(_s1), s2(_s2), s3(_s3) {} void draw(void) { s1->draw(); s2->draw(); s3->draw(); } void pack(void) { s1->offset_by(0,1); s2->offset_by(2,3); s3->offset_by(4,5); } void resize(void) { s1->set_dim(10,10); s2->set_dim(10,11); s3->set_dim(11,12); } }; // Two implementations of the Abstract datatype Shape class Rectangle: public Shape { float x, y; float width, height; public: Rectangle(const float _width, const float _height) : x(0), y(0), width(_width), height(_height) {} virtual void draw(void) { cerr << "Drawing a rectangle [" << x << ", " << y << "] - [" << (x+width) << ", " << (y+height) << "]" << endl; } virtual void offset_by(const float x, const float y) { this->x += x; this->y += y; } virtual void set_dim(const float width, const float height) { this->width = width; this->height = height; } }; class Ellipse: public Shape { float x, y; float width, height; public: Ellipse(const float _width, const float _height) : x(0), y(0), width(_width), height(_height) {} virtual void draw(void) { cerr << "Drawing an ellipse [" << x << ", " << y << "] axes " << width << " and " << height << endl; } virtual void offset_by(const float x, const float y) { this->x += x; this->y += y; } virtual void set_dim(const float width, const float height) { this->width = width; this->height = height; } }; // The test int main(void) { cerr << "Instantiating shapes..." << endl; Shapes shapes(new Rectangle(1,2), new Ellipse(5,5), new Rectangle(7,7)); cerr << "Drawing ..." << endl; shapes.draw(); cerr << "Packing ..." << endl; shapes.pack(); shapes.draw(); cerr << "Resizing .. " << endl; shapes.resize(); shapes.draw(); // Assume the garbage will be collected cerr << "\nAll done" << endl; return 0; }