Code Reuse by Inheritance a Point-Circle-Cylinder Class

Code Reuse by Inheritance a Point-Circle-Cylinder Class

90 Code Reuse by Inheritance C++ allows code reuse by defining new classes called derived classes by inheriting members of one or more base classes n Derived classes may modify inherited behavior and may define its own special data and function n Inheritance represents an IS-A relationship n Advantages of inheritance include - Software reuse: Group together common features in a base class - Easy to extend: New derived classes do not affect existing implementation and clients using base classes continue to work for all derived classes 91 A Point-Circle-Cylinder class hierarchy w A Point object can be specified by giving its position (coordinates) w A Circle object can be specified by giving its position (coordinates) and a radius w A Cylinder object can be specified by giving its position, a radius, and a height 92 The Point Class #ifndef POINT_H #define POINT_H #include <iostream> using std::ostream; class Point { public: explicit Point( int = 0, int = 0 ); // default constructor void setPoint( int, int ); // set coordinates int getX() const { return x; } // get x coordinate int getY() const { return y; } // get y coordinate void print(ostream &) const; // print the point object protected: // accessible to derived classes int x, y; // coordinates of the point }; //Nonmember overloaded output operator ostream &operator<<( ostream &, const Point & ); #endif 93 Meanings of the Inheritance Types w Public n public (protected)} members of the base class become n public (protected) members of the derived class w Protected n Both public and protected members of the base class become protected members of the derived class w Private n Both public and protected members of the base class become private members of the derived class 94 The Circle Class #ifndef CIRCLE_H #define CIRCLE_H #include "point.h" class Circle : public Point { public: explicit Circle(double r = 0.0):radius(r){}; // default constructor Circle( int x, int y, double r = 0.0); void setRadius( double ); // set radius double getRadius() const; // return radius double area() const; // calculate area void print(ostream &) const;// print the circle protected: // accessible to derived classes double radius; // radius of the Circle }; ostream &operator<<( ostream &, const Circle & ); #endif 95 The Point class Implementation 1 // Constructor for class Point Point::Point( int a, int b ) { setPoint( a, b ); } // Set the x and y coordinates void Point::setPoint( int a, int b ) { x = a; y = b; } void Point::print(ostream& ostr) const { ostr << '[' << x << ", " << y << ']' ; } // Overloaded insertion ostream& operator<<( ostream &ostr, const Point &p ){ p.print(ostr); return ostr; // enables cascading } 96 The Circle class Implementation const double Pi = 3.14159; // Constructor for Circle calls constructor for Point // with a member initializer and initializes radius Circle::Circle( double r, int a, int b ) : Point( a, b ){ // call base-class constructor setRadius( r ); } // Set radius void Circle::setRadius( double r ) { radius = ( r >= 0 ? r : 0 ); } // Get radius double Circle::getRadius() const { return radius; } 97 The Circle class Implementation // Calculate the area of a Circle double Circle::area() const { return Pi * radius * radius; } // Output a circle in the form: // Center = [x, y]; Radius = void Circle::print(ostream & ostr) const { ostr << "Center = " ; Point::print(ostr); ostr << "; Radius = " << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 2 ) << radius; } ostream& operator<<( ostream &ostr, const Circle &c ) { c.print(ostr); return ostr; // enables cascaded calls } 98 Properties of Derived Class Members Derived class members n cannot directly access private data members of the base class n if a base class function f() is redefined, the base version is referred to by baseClass::f() n the constructor, destructor, and assignment operators of a derived class should call, respectively, the constructor (as an initializer), destructor, and assignment operator of the base class n a friend of a base class is not automatically a friend of a derived class n redefining inherited function is not overloading: w with a base object, the base version is called w with a derived object, the derived version is called 99 Type Conversion w Every object of a derived class is also an object of base class w Assigning a derived object to a base object causes slicing, i.e., only base portion is copied w Assigning a derived-class pointer to a base-class pointer is always valid 2 w Assigning a base-class pointer to a derived-class pointer is dangerous, and requires an explicit casting derivedTypePtr = static_cast<derivedType *> baseTypePtr; w The type conversion rules apply to assignment, and parameter passing 100 The Cylinder Class class Cylinder : public Circle { public: explicit Cylinder( double h = 0.0): height(h){}; Cylinder( double h, double r, int x, int y); void setHeight( double ); // set height double getHeight() const; // return height double area() const; // calculate and return area double volume() const; // calculate and return volume void print(ostream &) const;// print the Cylinder protected: double height; // height of the Cylinder }; ostream &operator<<( ostream &, const Cylinder & ); 101 The Cylinder Class Implementation #include "cylinder.h" const double Pi = 3.14159; // Cylinder constructor calls Circle constructor Cylinder::Cylinder( double h, double r, int x, int y ) : Circle( r, x, y )// call base-class constructor { setHeight( h ); } // Set height of Cylinder void Cylinder::setHeight ( double h ){ height = ( h >= 0 ? h : 0 ); } // Get height of Cylinder double Cylinder:: getHeight() const { return height; } // Calculate the area of Cylinder (i.e., surface area) double Cylinder::area() const { return 2 * Circle::area() + 2 * Pi * radius * height; } // Calculate volume of Cylinder double Cylinder::volume() const { return Circle::area() * height; } // print the cylinder object void Cylinder::print(ostream &ostr ) const { Circle::print(ostr ); ostr << "; Height = " << height;} // Output Cylinder dimensions ostream &operator<<( ostream &ostr , const Cylinder &c ) { c.print(ostr); return ostr; // enables cascaded calls } 102 The Cylinder Class Implementation // Calculate volume of Cylinder double Cylinder::volume() const { return Circle::area() * height; } // print the cylinder object void Cylinder::print(ostream &ostr ) const { Circle::print(ostr ); ostr << "; Height = " << height; } // Output Cylinder dimensions ostream &operator<<( ostream &ostr , const Cylinder &c ) { 3 c.print(ostr); return ostr; // enables cascaded calls } 103 Testing the Point-Circle-Cylinder Hierarchy Circle c( 2.5, 37, 43 ); // You can call base (Point) class public member // functions via the derived class Circle object c cout << "X coordinate is " << c.getX() // Point's getX() and getY() << "\nY coordinate is " << c.getY() // are inherited << "\nRadius is " << c.getRadius(); c.setRadius( 4.25 ); c.setPoint( 2, 2 ); // Use inherited setPoint() cout << "\n\nThe new location and radius of c are\n" << c << "\nArea " << c.area() << '\n'; 104 Testing the Point-Circle-Cylinder Hierarchy Point p1 = c; //Slicing: Copy construct p1 using the Point part of c cout << "\nCircle printed as a Point is: " << p1 << endl; Point *pPtr = &c; // Can only refer to the "Point part" of c cout << "\nCircle printed as a Point is: " << *pPtr << endl; Circle* cPtr = &c; cout << "\nCircle printed via a pointer: " << *cPtr << endl; // create a Cylinder object Cylinder cyl( 5.7, 2.5, 12, 23 ); // use get functions to display the Cylinder cout << "X coordinate is " << cyl.getX() << "\nY coordinate is " << cyl.getY() << "\nRadius is " << cyl.getRadius() << "\nHeight is " << cyl.getHeight() << "\n\n"; // use set functions to change the Cylinder's attributes cyl.setHeight( 10 ); cyl.setRadius( 4.25 ); cyl.setPoint( 2, 2 ); cout << "The new location, radius, and height of cyl are:\n" << cyl << '\n'; // display the Cylinder as a Point Point &pRef1 = cyl; // pRef1 "thinks" that cyl is a Point cout << "\nCylinder printed as a Point is: " << pRef1 << "\n\n"; // display the Cylinder as a Circle Circle &circleRef = cyl; // circleRef thinks that cyl is a Circle cout << "Cylinder printed as a Circle is:\n" << circleRef << "\nArea: " << circleRef.area() << endl; return 0; } Test run: X coordinate is 10 Y coordinate is 37 Radius is 43 The new location and radius of c are Center = [2, 2]; Radius = 4.25 Area 56.74 4 Circle printed as a Point is: [2, 2] Circle printed as a Point is: [2, 2] Circle printed via a pointer: Center = [2, 2]; Radius = 4.25 The new location, radius, and height of cyl are: Center = [2, 2]; Radius = 4.25; Height = 10.00 Cylinder printed as a Point is: [2, 2] Cylinder printed as a Circle is: Center = [2, 2]; Radius = 4.25 Area: 56.74 105 Testing the Point-Circle-Cylinder Hierarchy Point p1 = c; //Slicing: Copy construct p1 using the Point part of c cout << "\nCircle printed as a Point is: " << p1 << endl; Point *pPtr = &c; // Can only refer to the "Point part" of c cout << "\nCircle printed as a Point is: " << *pPtr << endl; Circle* cPtr = &c; cout << "\nCircle printed via a pointer: " << *cPtr << endl; // create a Cylinder object Cylinder cyl( 5.7, 2.5, 12, 23 ); // use get functions to display the Cylinder cout << "X coordinate is " << cyl.getX() << "\nY coordinate is " << cyl.getY() << "\nRadius is " << cyl.getRadius() << "\nHeight is " << cyl.getHeight() << "\n\n"; // use set functions to change the Cylinder's attributes cyl.setHeight( 10 ); cyl.setRadius( 4.25 ); cyl.setPoint( 2, 2 ); cout << "The

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    9 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us