Professional Documents
Culture Documents
Introduction
Introduction
" Inheritance " Inheritance
# New classes created from existing classes # Single Inheritance
# Absorb attributes and behaviors. – Class inherits from one base class
" Polymorphism # Multiple Inheritance
# Write programs in a general fashion – Class inherits from multiple base classes
# Handle a wide variety of existing (and unspecified) # Three types of inheritance:
related classes – public: Derived objects are accessible by the base
class objects (focus of this chapter)
" Derived class
– private: Derived objects are inaccessible by the base
# Class that inherits data members and member class
functions from a previously defined base class – protected: Derived classes and friends can access
protected members of the base class
3 4
# Intermediate level of protection between public # Reverse not true - base class objects not a
and private inheritance derived-class object
# Derived-class members can refer to public and " Downcasting a pointer
protected members of the base class simply by # Use an explicit cast to convert a base-class
using the member names pointer to a derived-class pointer
# Note that protected data “breaks” encapsulation # Be sure that the type of the pointer matches the
type of object to which the pointer points
7 8
1 // point.h
2 // Definition of class Point
Casting Base-Class Pointers to Derived- 3
4
#ifndef POINT_H
#define POINT_H 1. Point class definition
Class Pointers 5
6
7
#include <iostream>
8 using std::ostream;
9
10 class Point { -------------
" Example 11 friend ostream &operator<<( ostream &, const Point & );
12
13
public:
Point( int = 0, int = 0 ); 1. Load header
// default constructor
# Circle class derived from the Point 14
15
void setPoint( int, int ); // set coordinates
int getX() const { return x; } // get x coordinate
base class 16
17
int getY() const { return y; } // get y coordinate
protected: // accessible by derived classes
20
reference a Circle object, and vice- 21
22
#endif
// Fig. 19.4: point.cpp
versa 23
24
// Member functions for class Point
#include <iostream>
25 #include "point.h"
26
27 // Constructor for class Point
28 Point::Point( int a, int b ) { setPoint( a, b ); }
29
30 // Set x and y coordinates of Point
31 void Point::setPoint( int a, int b )
9 32 { 10
33 x = a;
55 using std::ios;
81 Circle::Circle( double r, int a, int b )
82 : Point( a, b )
1.1 Function Definitions
// call base-class constructor
56 using std::setiosflags;
57 using std::setprecision; 83 { setRadius( r ); }
58
84
59 #include "point.h"
60 85 // Set radius of Circle
61 class Circle : public Point { // Circle inherits from Point 86 void Circle::setRadius( double r )
62 friend ostream &operator<<( ostream &, const Circle & );
87 { radius = ( r >= 0 ? r : 0 ); }
63 public: 11 12
64 // default constructor 88
89 // Get radius of Circle 122 Circle *circlePtr = 0, c( 2.7, 120, 89 );
90 double Circle::getRadius() const { return radius; } 123
91
92 // Calculate area of Circle 124 cout << "Point p: " << p << "\nCircle c: " << c << '\n';
93 double Circle::area() const 125
94 { return 3.14159 * radius * radius; } 126 // Treat a Circle as a Point (see only the base class part)
95
96 // Output a Circle in the form:
1. 1 Function Definitions 127 pointPtr = &c; 1.1 Initialize objects
// assign address of Circle to pointPtr
97 // Center = [x, y]; Radius = #.## 128 cout << "\nCircle c (via *pointPtr): "
98 ostream &operator<<( ostream &output, const Circle &c ) 129 << *pointPtr << '\n';
99 {
100 output << "Center = " << static_cast< Point >( c ) 130
101
102
<< "; Radius = "
----------------------
<< setiosflags( ios::fixed | ios::showpoint )
131
132
1.2 Assign objects
// Treat a Circle as a Circle (with some casting)
// cast base-class pointer to derived-class pointer
103 << setprecision( 2 ) << c.radius;
104 133 circlePtr = static_cast< Circle * >( pointPtr );
105
106 }
return output; // enables cascaded calls
Driver 134
135
cout << "\nCircle c (via *circlePtr):\n" << *circlePtr
<< "\nArea of c (via circlePtr): "
107 // Fig. 19.4: fig19_04.cpp
108 // Casting base-class pointers to derived-class pointers 136 << circlePtr->area() << '\n'; 2. Function calls
109 #include <iostream> 137
110 138 // DANGEROUS: Treat a Point as a Circle
111 using std::cout; 1. Load headers 139 pointPtr = &p; // assign address of Point to pointPtr
112 using std::endl;
140
113
141 // cast base-class pointer to derived-class pointer
114 #include <iomanip>
115 142 circlePtr = static_cast< Circle * >( pointPtr );
116 #include "point.h"
117 #include "circle.h"
1.1 Initialize objects 143
144
cout << "\nPoint p (via *circlePtr):\n" << *circlePtr
<< "\nArea of object circlePtr points to: "
118
145 << circlePtr->area() << endl;
119 int main()
120 { 13 146 return 0; 14
121 Point *pointPtr = 0, p( 30, 50 ); 147}
15 16
1 // employ.h
2 // Definition of class Employee
Overriding Base-Class Members in a 3
4
#ifndef EMPLOY_H
#define EMPLOY_H
Derived Class
5
6 class Employee {
1. Employee class definition
7 public:
8 Employee( const char *, const char * ); // constructor
derived class 22
23 #include <cstring>
24 #include <cassert>
25 #include "employ.h"
26
27 // Constructor dynamically allocates space for the
28 // first and last name and uses strcpy to copy
29 // the first and last names into the object.
30 Employee::Employee( const char *first, const char *last )
17 31 { 18
32 firstName = new char[ strlen( first ) + 1 ];
33 assert( firstName != 0 ); // terminate if not allocated 64 double wage; // wage per hour
34 strcpy( firstName, first ); 65 double hours; // hours worked for week
35 66 };
36 lastName = new char[ strlen( last ) + 1 ]; 67
37
38
1.1 Function definitions
assert( lastName != 0 ); // terminate if not allocated
strcpy( lastName, last );
68
69
#endif
// hourly.cpp
39 } 70 // Member function definitions for class HourlyWorker
40
41 // Output employee name
71
72
#include <iostream>
1. Load header
42 void Employee::print() const 73 using std::cout;
43
44
{ cout << firstName << ' ' << lastName; } --------------------- 74
75
using std::endl;
96
97 // Print the HourlyWorker's name and pay
98 void HourlyWorker::print() const
public, private, and protected
99 { 1.1 Function Definitions
100 cout << "HourlyWorker::print() is executing\n\n"; Inheritance
101 Employee::print(); // call base-class print function
102 Base Type of
class inheritance
103
104
--------------------
cout << " is an hourly worker with pay of $"
<< setiosflags( ios::fixed | ios::showpoint )
member
access
specifier
public protected private
105
106 }
1. Load header
<< setprecision( 2 ) << getPay() << endl; inheritance inheritance
111
protected in derived protected in derived private in derived
class. class. class.
112 int main() protected
2. Function call
113 { Can be accessed directly by Can be accessed directly by Can be accessed directly by
all non-static member all non-static member all non-static member
functions and friend functions and friend functions and friend
114 HourlyWorker h( "Bob", "Smith", 40.0, 10.00 ); functions. functions. functions.
115 h.print();
Hidden in derived class. Hidden in derived class. Hidden in derived class.
116 return 0;
private Can be accessed by non- Can be accessed by non- Can be accessed by non-
117 } static member functions static member functions static member functions
and friend functions and friend functions and friend functions
HourlyWorker::print() is executing through public or through public or through public or
21 protected member protected member protected member 22
functions of the base class. functions of the base class. functions of the base class.
Bob Smith is an hourly worker with pay of $400.00
23 24
1 // point2.h
2 // Definition of class Point
Using Constructors and Destructors in 3
4
#ifndef POINT2_H
#define POINT2_H
Derived Classes 5
6 class Point {
1. Point definition
7 public:
8 Point( int = 0, int = 0 ); // default constructor
9 ~Point(); // destructor
" Destructors are called in the reverse order of 19 using std::cout; 1.1 Function definitions
20 using std::endl;
constructor calls. 21
22 #include "point2.h"
# Derived-class destructor is called before its base-class 23
24 // Constructor for class Point
destructor 25 Point::Point( int a, int b )
26 {
27 x = a;
28 y = b;
29
30 cout << "Point constructor: "
25 31 << '[' << x << ", " << y << ']' << endl;
26
32 }
33 58 // circle2.cpp
34 // Destructor for class Point 59 // Member function definitions for class Circle
35 Point::~Point() 60 #include <iostream>
36 { 61
37 cout << "Point destructor: " 62 using std::cout;
38
1.1 Function definitions
<< '[' << x << ", " << y << ']' << endl; 63 using std::endl; 1. Load header
39 } 64
40 // circle2.h 65 #include "circle2.h"
41 // Definition of class Circle 66
42 #ifndef CIRCLE2_H
43 #define CIRCLE2_H
---------------------- 1.1 Function Definitions
67 // Constructor for Circle calls constructor for Point
68 Circle::Circle( double r, int a, int b )
44
45 #include "point2.h" 1. Load header 69
70 {
: Point( a, b ) // call base-class constructor
46
71 radius = r; // should validate
47 class Circle : public Point {
72 cout << "Circle constructor: radius is "
48 public:
49 // default constructor 1.1 Circle Definition 73
74 }
<< radius << " [" << x << ", " << y << ']' << endl;
54 double radius; 78 {
56 27 80 << radius << " [" << x << ", " << y << ']' << endl; 28
57 #endif 81 }
82 // Example.cpp
83 // Demonstrate when base-class and derived-class
84 // constructors and destructors are called. Program Output
85 #include <iostream>
86
87 using std::cout;
1. Load headers
88 using std::endl;
89
90 #include "point2.h"
Point constructor: [11, 22]
91 #include "circle2.h" 1.1 Initialize objects Point destructor: [11, 22]
92
93 int main()
Point constructor: [72, 29]
94 {
Circle constructor: radius is 4.5 [72, 29]
95 2. Objects enter and leave scope
// Show constructor and destructor calls for Point
Point constructor: [5, 5]
96 {
97 Point p( 11, 22 );
Circle constructor: radius is 10 [5, 5]
98 }
99
Circle destructor: radius is 10 [5, 5]
100 cout << endl;
Point destructor: [5, 5]
101 Circle circle1( 4.5, 72, 29 );
Circle destructor: radius is 4.5 [72, 29]
102 cout << endl;
Point destructor: [72, 29]
103 Circle circle2( 10, 5, 5 );
104 cout << endl;
105 return 0; 29 30
106 }
Implicit Derived-Class Object to Base- Implicit Derived-Class Object to Base-
Class Object Conversion Class Object Conversion
35 36
1 // point2.h
2 // Definition of class Point
3 #ifndef POINT2_H
4 #define POINT2_H 1.1 Function definitions
5
6 #include <iostream> 1. Point definition
7
8 using std::ostream;
9
10 class Point {
33 y = b;
11
12 public:
1.1 Function definitions
friend ostream &operator<<( ostream &, const Point & );
34 }
13 Point( int = 0, int = 0 ); // default constructor 35
14 void setPoint( int, int ); // set coordinates 36 // Output the Point
15 int getX() const { return x; } // get x coordinate 37 ostream &operator<<( ostream &output, const Point &p )
16 int getY() const { return y; } // get y coordinate 38 {
17 protected: // accessible to derived classes 39 output << '[' << p.x << ", " << p.y << ']';
18 int x, y; // coordinates of the point
40
19 };
20 41 return output; // enables cascading
21 #endif 42 }
22 // point2.cpp
23 // Member functions for class Point
24 #include "point2.h"
25
26 // Constructor for class Point
27 Point::Point( int a, int b ) { setPoint( a, b ); }
28
29 // Set the x and y coordinates
30 void Point::setPoint( int a, int b )
31 { 37 38
32 x = a;
1 // circle2.h 34
2 // Definition of class Circle 35 // Constructor for Circle calls constructor for Point
3 #ifndef CIRCLE2_H
36 // with a member initializer and initializes radius
4 #define CIRCLE2_H
5 37 Circle::Circle( double r, int a, int b )
6
7
#include <iostream> 1. Circle definition 38 : Point( a, b )
39 { setRadius( r ); }
// call base-class constructor
8 using std::ostream; 40
9
10 #include "point2.h"
41 // Set radius 1.1 Function definitions
11 42 void Circle::setRadius( double r )
12
13
class Circle : public Point { 1.1 Function definitions
friend ostream &operator<<( ostream &, const Circle & );
43
44
{ radius = ( r >= 0 ? r : 0 ); }
14 public:
45 // Get radius
15 // default constructor
16 Circle( double r = 0.0, int x = 0, int y = 0 ); 46 double Circle::getRadius() const { return radius; }
17 void setRadius( double ); // set radius 47
18 double getRadius() const; // return radius 48 // Calculate area of Circle
19 double area() const; // calculate area 49 double Circle::area() const
20 protected: // accessible to derived classes
50 { return 3.14159 * radius * radius; }
21 double radius; // radius of the Circle
22 }; 51
23 52 // Output a circle in the form:
24 #endif 53 // Center = [x, y]; Radius = #.##
25 // circle2.cpp
54 ostream &operator<<( ostream &output, const Circle &c )
26 // Member function definitions for class Circle 55 {
27 #include <iomanip> 56 output << "Center = " << static_cast< Point > ( c )
28 57 << "; Radius = "
29 using std::ios; 58 << setiosflags( ios::fixed | ios::showpoint )
30 using std::setiosflags; 59 << setprecision( 2 ) << c.radius;
31 using std::setprecision; 60
32 39 61 return output; // enables cascaded calls 40
33 #include "circle2.h" 62 }
1 // cylindr2.h 30 // cylindr2.cpp
2 // Definition of class Cylinder 31 // Member and friend function definitions
3 #ifndef CYLINDR2_H 32 // for class Cylinder.
4 #define CYLINDR2_H 33 #include "cylindr2.h"
5 34
6 #include <iostream> 35 // Cylinder constructor calls Circle constructor
7
36
37 : Circle( r, x, y )
1.1 Function definitions
Cylinder::Cylinder( double h, double r, int x, int y )
// call base-class constructor
8
9
using std::ostream;
1. Cylinder definition 38 { setHeight( h ); }
39
10 #include "circle2.h"
40 // Set height of Cylinder
11 41 void Cylinder::setHeight( double h )
12 class Cylinder : public Circle { 42 { height = ( h >= 0 ? h : 0 ); }
13 friend ostream &operator<<( ostream &, const Cylinder & ); 43
14 44 // Get height of Cylinder
15 public: 45 double Cylinder::getHeight() const { return height; }
16 // default constructor 46
17 Cylinder( double h = 0.0, double r = 0.0, 47 // Calculate area of Cylinder (i.e., surface area)
18 int x = 0, int y = 0 ); 48 double Cylinder::area() const
19 49 {
20 void setHeight( double ); // set height 50 return 2 * Circle::area() +
51 2 * 3.14159 * radius * height;
21 double getHeight() const; // return height
52 }
22 double area() const; // calculate and return area
53
23 double volume() const; // calculate and return volume
54 // Calculate volume of Cylinder
24
55 double Cylinder::volume() const
25 protected: 56 { return Circle::area() * height; }
26 double height; // height of the Cylinder 57
27 }; 58 // Output Cylinder dimensions
28 41 59 ostream &operator<<( ostream &output, const Cylinder &c ) 42
29 #endif 60 {
61 output << static_cast< Circle >( c ) 92 cout << "The new location, radius, and height of cyl are:\n"
62 << "; Height = " << c.height; 93 << cyl << '\n';
63 94
64
65 }
return output; 1.1 Function definitions
// enables cascaded calls
95
96
cout << "The area of cyl is:\n"
<< cyl.area() << '\n';
97
66
67
// Example.cpp
// Driver for class Cylinder ---------------------- 98
99
// display the Cylinder as a Point
Point &pRef = cyl; // pRef "thinks" it is a Point
68 #include <iostream> 100 cout << "\nCylinder printed as a Point is: "
69
70 using std::cout;
Driver 101
102
<< pRef << "\n\n";
71 using std::endl;
72
73 #include "point2.h"
1. Load headers 103
104
// display the Cylinder as a Circle
Circle &circleRef = cyl; // circleRef thinks it is a Circle
105 cout << "Cylinder printed as a Circle is:\n" << circleRef
74
75
#include "circle2.h"
#include "cylindr2.h" 1.1 Initialize object 106
107
<< "\nArea: " << circleRef.area() << endl;
76
77 int main()
2. Function calls
108
109}
return 0;
3. Output
78 {
79
80
// create Cylinder object
Cylinder cyl( 5.7, 2.5, 12, 23 ); 2.1 Change attributes
X coordinate is 12
Y coordinate is 23
Program Output
81 Radius is 2.5
Height is 5.7
82 // use get functions to display the Cylinder
83 cout << "X coordinate is " << cyl.getX() 3. Output The new location, radius, and height of cyl are:
84 << "\nY coordinate is " << cyl.getY() Center = [2, 2]; Radius = 4.25; Height = 10.00
85 << "\nRadius is " << cyl.getRadius() The area of cyl is:
86 << "\nHeight is " << cyl.getHeight() << "\n\n"; 380.53
Cylinder printed as a Point is: [2, 2]
87
88 // use set functions to change the Cylinder's attributes Cylinder printed as a Circle is:
89 cyl.setHeight( 10 ); Center = [2, 2]; Radius = 4.25
90 cyl.setRadius( 4.25 ); 43 Area: 56.74 44
91 cyl.setPoint( 2, 2 );