====================================================================== Faculty of Applied Science and Engineering, University of Toronto CSC181: Introduction to Computer Programming, Fall 2000 Tutorial Notes, Week 12 ====================================================================== ----------------- Summary of Topics ----------------- - Inheritance - Virtual functions ------- Example ------- The example below models a small class hierarchy of shapes. The base class is Shape, and Rectangle and Circle are subclasses (or derived classes) of Shape. The Shape class has two virtual functions, print and getArea. Rectangle overrides (or redefines) both of these functions, but Circle overrides only getArea. The results of invoking print and getArea on Rectangle and Circle can be seen below. Note that because Shape contains one pure virtual function, it is an abstract class; that is, no instances of Shape can be created. ---- Code ---- #include const double PI = 3.1416; struct Point { int x; int y; Point() { x = 0; y = 0; } Point(int x, int y) { this->x = x; this->y = y; } void print(ostream& os) const { os << "(" << x << ", " << y << ")"; } }; class Shape { private: Point centre; public: Shape() {} Shape(const Point& c) : centre(c) {} const Point& getCentre() const { return centre; } virtual void print(ostream& os) const { centre.print(os); } virtual double getArea() const = 0; }; class Rectangle : public Shape { private: int width; int height; public: Rectangle(const Point& c, int w, int h) : Shape(c), width(w), height(h) {} int getWidth() const { return width; } int getHeight() const { return height; } virtual void print(ostream& os) const { Shape::print(os); os << " width = " << width << ", height = " << height; } double getArea() const { return width*height; } }; class Circle : public Shape { private: int radius; public: Circle(const Point& c, int r) : Shape(c), radius(r) {} int getRadius() const { return radius; } double getArea() const { return PI*radius*radius; } }; class ShapeList { private: Shape** shapes; int capacity; int nShapes; public: ShapeList(int c) : capacity(c), nShapes(0) { shapes = new Shape*[c]; } void add(Shape* s) { shapes[nShapes++] = s; } Shape* get(int i) const { return shapes[i]; } int size() { return nShapes; } ~ShapeList() { delete[] shapes; } }; ostream& operator<< (ostream& os, const Shape& s) { s.print(os); return os; } int main(void) { ShapeList shapes = 15; shapes.add(new Rectangle(Point(5, 4), 2, 9)); shapes.add(new Circle(Point(0, 0), 3)); shapes.add(new Rectangle(Point(3, 2), 4, 5)); int i; for (i = 0; i != shapes.size(); i++) { cout << shapes.get(i)->getArea() << endl; } cout << "--" << endl; for (i = 0; i != shapes.size(); i++) { cout << *(shapes.get(i)) << endl; } cout << "--" << endl; return 0; } ------ Output ------ 18 28.2744 20 -- (5, 4) width = 2, height = 9 (0, 0) (3, 2) width = 4, height = 5 --