Ooops
Ooops
11-09-2022 1
Textbook for C++
• Mastering C++ K.R Venugopal Rajkumar, TMH.
11-09-2022 2
Why New Programming Paradigm?
• To Keep up with the pace of hardware development.
• To build more reliable and reusable systems.
11-09-2022 3
Evolution of Programming Paradigms
• Monolithic Programming
Only global data and sequential code.
Flow control is achieved through jumps,
Program code is copied for reuse
No subroutine support
No support for data abstraction (ability to create user- defined data types for
modelling real world object)
Difficult to maintain or enhance the program code
11-09-2022 4
• Procedural Programming
Programs are organized in the form of subroutines and all data items are
global
Program controls are through jumps (goto’s) and call subroutines
Abstracted subroutines are used to avoid repetition
Software application is minimized
Difficult to maintain and enhance the program code
11-09-2022 5
• Structured Programming
11-09-2022 6
• Object Oriented Programming
Emphasis is on data rather than procedure.
Programs are divided into what are known as objects.
Data structures are designed such that they characterize the objects.
Functions that operate on the data of an object are ties together in the data
structure.
Data is hidden and cannot be accessed by external function.
Objects may communicate with each other through function.
New data and functions can be easily added whenever necessary.
Follows bottom up approach in program design.
11-09-2022 7
Structured Vs. Object Oriented
• Structured views the two core elements of any program – data and
functions as two separate entities.
• OOP views them as a single entity.
11-09-2022 8
Elements of Object Oriented Programming
• Objects
Objects are the basic run time entities in an object-oriented system.
They may represent a person, a place, a bank account, a table of data or any
item that the program has to handle.
They may also represent user-defined data such as vectors, time and lists.
Programming problem is analyzed in term of objects and the nature of
communication between them.
Program objects should be chosen such that they match closely with the real-
world objects.
Objects take up space in the memory and have an associated address like a
record in Pascal, or a structure in c.
11-09-2022 9
When a program is executed, the objects
interact by sending messages to one another.
For example, if “customer” and “account” are to
object in a program, then the customer object
may send a message to the count object
requesting for the bank balance.
Each object contain data, and code to
manipulate data.
Objects can interact without having to know
details of each other’s data or code.
It is a sufficient to know the type of message
accepted, and the type of response returned by
the objects
11-09-2022 10
• Classes
The entire set of data and code of an object can be made a user-defined data
type with the help of class.
In fact, objects are variables of the type class.
Once a class has been defined, we can create any number of objects
belonging to that class.
Each object is associated with the data of type class with which they are
created.
A class is thus a collection of objects similar types.
For examples, Mango, Apple and orange members of class fruit.
Classes are user-defined that types and behave like the built-in types of a
programming language.
11-09-2022 11
• Encapsulation
The wrapping up of data and function into a single unit (called class) is known
as encapsulation. Data and encapsulation is the most striking feature of a
class.
The data is not accessible to the outside world, and only those functions
which are wrapped in the class can access it.
These functions provide the interface between the object’s data and the
program.
This insulation of the data from direct access by the program is called data
hiding or information hiding
11-09-2022 12
• Abstraction
Abstraction refers to the act of representing essential features without
including the background details or explanation.
Classes use the concept of abstraction and are defined as a list of abstract
attributes such as size, wait, and cost, and function operate on these
attributes.
They encapsulate all the essential properties of the object that are to be
created.
The attributes are some time called data members because they hold
information.
The functions that operate on these data are sometimes called methods or
member function.
11-09-2022 13
• Inheritance
Inheritance is the process by which objects of one class acquired the properties of
objects of another classes.
It supports the concept of hierarchical classification.
For example, the bird, ‘robin’ is a part of class ‘flying bird’ which is again a part of the
class ‘bird’.
The principal behind this sort of division is that each derived class shares common
characteristics with the class from which it is derived.
In OOP, the concept of inheritance provides the idea of reusability.
This means that we can add additional features to an existing class without
modifying it.
This is possible by deriving a new class from the existing one.
The new class will have the combined feature of both the classes.
11-09-2022 14
• Polymorphism
Polymorphism is another important OOP concept.
Polymorphism, a Greek term, means the ability to take more than on form. An operation may exhibit
different behavior is different instances.
The behavior depends upon the types of data used in the operation.
For example, consider the operation of addition. For two numbers, the operation will generate a sum. If
the operands are strings, then the operation would produce a third string by concatenation.
The process of making an operator to exhibit different behaviors in different instances is known as
operator overloading.
A single function name can be used to handle different number and different types of argument. This is
something similar to a particular word having several different meanings depending upon the context.
Using a single function name to perform different type of task is known as function overloading.
Polymorphism plays an important role in allowing objects having different internal structures to share
the same external interface.
This means that a general class of operations may be accessed in the same manner even though
specific action associated with each operation may differ.
Polymorphism is extensively used in implementing inheritance.
11-09-2022 15
• Dynamic Binding
Binding refers to the linking of a procedure call to the code to be executed in
response to the call.
Dynamic binding means that the code associated with a given procedure call
is not known until the time of the call at run time.
It is associated with polymorphism and inheritance.
A function call associated with a polymorphic reference depends on the
dynamic type of that reference
11-09-2022 16
Moving from C to C++
• Stream Based I/O
• Streams are abstractions that refer to data flow.
• Output streams : allow to perform write operations on output devices like
screen, disk etc.
• cout << “Hello” << x << endl;
• Input streams : allow to perform read operation with input devices like
keyboard, disk, etc.
• cin >> name >> age >> address;
11-09-2022 17
• Literals – Constant Qualifiers
• #define preprocessor directive
• Enumerated data types
• const keyword: cannot modify the variable during run-time
• Scope Resolution Operator ::
• :: GlobalVariableName
• Scope resolution operator allows us to reference an identifier in the global scope that
has been hidden by another identifier with the same name in local scope.
• Variable definition is allowed at the point of Use.
11-09-2022 18
• Variable Aliases – Reference Variables
• Datatype &ReferenceVariable = ValueVariable
• int b = 5;
• int &a=b;
• Reference variable enjoys the simplicity of value variable and power of the
pointer variable.
• No alias for constant value. Eg: int &n = 5; //invalid
• Reference Variables are not bounded to a new memory location, but to the
variables to which they are aliases.
11-09-2022 19
• Strict Type Checking
• In C++ the function prototyping is compulsory, if the function definition is not placed,
before the function call.
• Parameters Passing By reference
• Inline Functions
• Function Overloading
• Functions as a part of a struct
• Type Conversion
• Function templates
• Runtime Memory management
11-09-2022 20
Functions as a part of a struct
struct structname
{
public:
//data and functions
private:
//data and functions
protected:
//data and functions
}
Public, protected, private are access specifiers.
If none specified, by default public.
The private and protected
11-09-2022 21
FUNCTION TEMPLATES
Finding the Maximum of Two Integers
Here’s a small function that you might write to find
the maximum of two integers.
int maximum(int a, int b)
{
if (a > b)
return a;
else
return b;
}
11-09-2022 22
Finding the Maximum of Two Doubles
11-09-2022 23
One Hundred Million Functions...
11-09-2022 24
A Template Function for Maximum
11-09-2022 25
A Template Function for Maximum
11-09-2022 26
A Template Function for Maximum
11-09-2022 27
Using a Template Function
11-09-2022 28
Finding the Maximum Item in an Array
11-09-2022 31
3 Kinds of Program Data
• STATIC DATA: Allocated at compiler time
11-09-2022 32
Dynamic Memory Allocation Diagram
High-end
Run-time allocated
Stack
memory
Heap
Compile-time
static data
allocated
memory
Program
code
Low-end
11-09-2022 33
Dynamic Memory Allocation
• In C, functions such as malloc() are used to
dynamically allocate memory from the Heap.
• In C++, this is accomplished using the new and delete
operators
• new is used to allocate memory during execution time
• returns a pointer to the address where the object is to be
stored
• always returns a pointer to the type that follows the new
11-09-2022 34
Operator new Syntax
new DataType
35
11-09-2022 35
Operator new
2000
char* ptr;
???
5000
ptr
11-09-2022 36
The NULL Pointer
• There is a pointer constant called the “null pointer”
denoted by NULL
• But NULL is not memory address 0.
delete Pointer
delete [ ] Pointer
ptr
5000
*ptr = ‘B’;
‘B’
11-09-2022 39
Example
char *ptr ;
3000
ptr
ptr = new char[ 5 ]; ???
NULL
6000
???
11-09-2022 40
‘this’ pointer in C++
• To understand ‘this’ pointer, it is important to know how objects look at functions
and data members of a class.
11-09-2022 43
2) To return reference to the calling object
/* Reference to the calling object • When a reference to a local
can be returned */ object is returned, the returned
Test& Test::func () reference can be used to chain
function calls on a single object.
{
// Some processing
return *this;
}
11-09-2022 44
class Test int main()
{ {
private: Test obj1(5, 5);
int x;
int y; // Chained function calls. All calls modify the same object
public: // as the same object is returned by reference
Test(int x = 0, int y = 0) { this->x = x; this->y = y; } obj1.setX(10).setY(20);
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; } obj1.print();
void print() { cout << "x = " << x << " y = " << y << endl; } return 0;
}; }
Output:
x = 10 y = 20
11-09-2022 45
Keywords in C++
11-09-2022 46
Introduction
• Object-oriented programming (OOP)
• Encapsulation: encapsulates data (attributes) and
functions (behavior) into packages called classes
• Information hiding : implementation details are hidden
within the classes themselves
• Classes
• Classes are the standard unit of programming
• A class is like a blueprint – reusable
• Objects are instantiated (created) from the class
• For example, a house is an instance of a “blueprint
class”
11-09-2022 47
Structure Definitions
• Structures
• Aggregate data types built using elements of other types
11-09-2022 48
Structure Definitions
• Self-referential structure
• Contains a member that is a pointer to the same
structure type
• Used for linked lists, queues, stacks and trees
• struct
• Creates a new data type that is used to declare
variables
• Structure variables are declared like variables of other
types
• Example:
Time timeObject, timeArray[ 10 ],
*timePtr, &timeRef = timeObject;
11-09-2022 49
Accessing Members of Structures
• Member access operators:
• Dot operator (.) for structures and objects
• Arrow operator (->) for pointers
• Print member hour of timeObject:
cout << timeObject.hour;
OR
timePtr = &timeObject;
cout << timePtr->hour;
• timePtr->hour is the same as ( *timePtr ).hour
• Parentheses required: * has lower precedence than .
11-09-2022 50
2 // Create a structure, set its members, and print it.
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 struct Time { // structure definition
9 int hour; // 0-23
10 int minute; // 0-59
11 int second; // 0-59
12 };
13
14 void printMilitary( const Time & ); // prototype
15 void printStandard( const Time & ); // prototype
16
17 int main()
18 {
19 Time dinnerTime; // variable of new type Time
20
21 // set members to valid values
22 dinnerTime.hour = 18;
23 dinnerTime.minute = 30;
24 dinnerTime.second = 0;
25
26 cout << "Dinner will be held at ";
27 printMilitary( dinnerTime ); Dinner will be held at 18:30 military time,
28 cout << " military time,\nwhich is "; which is 6:30:00 PM standard time.
29 printStandard( dinnerTime );
11-09-202230 cout << " standard time.\n"; 51
31
32 // set members to invalid values
33 dinnerTime.hour = 29;
34 dinnerTime.minute = 73;
35
36 cout << "\nTime with invalid values: ";
37 printMilitary( dinnerTime );
Time with invalid values: 29:73
38 cout << endl;
39 return 0;
40 }
41
42 // Print the time in military format
43 void printMilitary( const Time &t )
44 {
45 cout << ( t.hour < 10 ? "0" : "" ) << t.hour << ":"
46 << ( t.minute < 10 ? "0" : "" ) << t.minute;
47 }
48
49 // Print the time in standard format
50 void printStandard( const Time &t )
51 {
52 cout << ( ( t.hour == 0 || t.hour == 12 ) ?
53 12 : t.hour % 12 )
54 << ":" << ( t.minute < 10 ? "0" : "" ) << t.minute
55 << ":" << ( t.second < 10 ? "0" : "" ) << t.second
56 << ( t.hour < 12 ? " AM" : " PM" );
11-09-2022 52
57 }
Dinner will be held at 18:30 military time,
which is 6:30:00 PM standard time.
Program Output
11-09-2022 53
Implementing a Time Abstract Data Type
with a Class
• Classes
• Model objects that have attributes (data members) and
behaviors (member functions)
• Defined using keyword class
• Have a body delineated with braces ({ and })
• Class definitions terminate with a semicolon
• Example:
11-09-2022 54
1 class Time {
2 public: Public: and Private: are
3 Time(); member-access specifiers.
4 void setTime( int, int, int );
5 void printMilitary(); setTime, printMilitary, and
6 void printStandard(); printStandard are member
7 private: functions.
Time is the constructor.
8 int hour; // 0 - 23
9 int minute; // 0 - 59
10 int second; // 0 - 59 hour, minute, and
11 }; second are data members.
11-09-2022 55
Implementing a Time Abstract Data Type with
a Class
• Member access specifiers
• Classes can limit the access to their member functions and data
• The three types of access a class can grant are:
• Public — Accessible wherever the program has access to an object of
the class
• private — Accessible only to member functions of the class
• Protected — Similar to private and discussed later
• Constructor
• Special member function that initializes the data members of a
class object
• Cannot return values
• Have the same name as the class
11-09-2022 56
Objects
• Class definition and declaration
• Once a class has been defined, it can be used as a type
in object, array and pointer declarations
• Example:
11-09-2022 57
2 // Time class.
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 // Time abstract data type (ADT) definition
9 class Time {
10 public:
11 Time(); // constructor
12 void setTime( int, int, int ); // set hour, minute, second
13 void printMilitary(); // print military time format
14 void printStandard(); // print standard time format
15 private:
16 int hour; // 0 – 23
17 int minute; // 0 – 59
18 int second; // 0 – 59
19 };
20
21 // Time constructor initializes each data member to zero.
22 // Ensures all Time objects start in a consistent state. Note the :: preceding
23 Time::Time() { hour = minute = second = 0; }
the function names.
24
25 // Set a new Time value using military time. Perform validity
26 // checks on the data values. Set invalid values to zero.
27 void Time::setTime( int h, int m, int s )
28 {
29 hour = ( h >= 0 && h < 24 ) ? h : 0;
30 minute = ( m >= 0 && m < 60 ) ? m : 0;
11-09-202231 second = ( s >= 0 && s < 60 ) ? s : 0; 58
32 }
33
34 // Print Time in military format
35 void Time::printMilitary()
36 {
37 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
38 << ( minute < 10 ? "0" : "" ) << minute;
39 }
40
41 // Print Time in standard format
42 void Time::printStandard()
43 {
44 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
45 << ":" << ( minute < 10 ? "0" : "" ) << minute
46 << ":" << ( second < 10 ? "0" : "" ) << second
47 << ( hour < 12 ? " AM" : " PM" );
48 }
49
50 // Driver to test simple class Time
51 int main()
52 {
53 Time t; // instantiate object t of class Time
54
55 cout << "The initial military time is ";
56 t.printMilitary();
57 cout << "\nThe initial standard time is ";
58 t.printStandard();
59
11-09-2022 59
60 t.setTime( 13, 27, 6 );
61 cout << "\n\nMilitary time after setTime is ";
62 t.printMilitary();
63 cout << "\nStandard time after setTime is ";
64 t.printStandard();
65
66 t.setTime( 99, 99, 99 ); // attempt invalid settings
67 cout << "\n\nAfter attempting invalid settings:"
68 << "\nMilitary time: ";
69 t.printMilitary();
70 cout << "\nStandard time: ";
71 t.printStandard();
72 cout << endl;
73 return 0;
74 }
11-09-2022 60
Implementing a Time ADT with a Class
• Destructors
• Functions with the same name as the class but
preceded with a tilde character (~)
• Cannot take arguments and cannot be overloaded
• Performs “termination housekeeping”
• Binary scope resolution operator (::)
• Combines the class name with the member function
name
• Different classes can have member functions with the
same name
• Format for defining member functions
ReturnType ClassName::MemberFunctionName( ){
…
}
11-09-2022 61
Implementing a Time ADT with a Class
11-09-2022 62
Class Scope and Accessing Class
Members
• Class scope
• Data members and member functions
• File scope
• Nonmember functions
• Inside a scope
• Members accessible by all member functions
• Referenced by name
• Outside a scope
• Members are referenced through handles
• An object name, a reference to an object or a pointer to an object
11-09-2022 63
Class Scope and Accessing Class
Members
• Function scope
• Variables only known to function they are defined in
• Variables are destroyed after function completion
• Accessing class members
• Same as structs
• Dot (.) for objects and arrow (->) for pointers
• Example:
• t.hour is the hour element of t
• TimePtr->hour is the hour element
11-09-2022 64
1 // Fig. 6.4: fig06_04.cpp
2 // Demonstrating the class member access operators . and ->
3 //
4 // CAUTION: IN FUTURE EXAMPLES WE AVOID PUBLIC DATA!
5 #include <iostream>
6
7 using std::cout;
8 using std::endl;
9
10 // Simple class Count
11 class Count {
12 public:
13 int x;
14 void print() { cout << x << endl; }
15 };
16
17 int main()
18 {
19 Count counter, // create counter object
20 *counterPtr = &counter, // pointer to counter
21 &counterRef = counter; // reference to counter
22
23 cout << "Assign 7 to x and print using the object's name: ";
24 counter.x = 7; // assign 7 to data member x
25 counter.print(); // call member function print
26
27 cout << "Assign 8 to x and print using a reference: ";
28 counterRef.x = 8; // assign 8 to data member x
11-09-202229 counterRef.print(); // call member function print 65
30
31 cout << "Assign 10 to x and print using a pointer: ";
32 counterPtr->x = 10; // assign 10 to data member x
34 return 0;
35 }
11-09-2022 66
Separating Interface from
Implementation
• Separating interface from implementation
• Makes it easier to modify programs
• Header files
• Contains class definitions and function prototypes
• Source-code files
• Contains member function definitions
11-09-2022 67
1 // time1.h
2 // Declaration of the Time class.
3 // Member functions are defined in time1.cpp
4
5 // prevent multiple inclusions of header file
6 #ifndef TIME1_H
7 #define TIME1_H
8
9 // Time abstract data type definition
10 class Time {
11 public:
12 Time(); // constructor
13 void setTime( int, int, int ); // set hour, minute, second
14 void printMilitary(); // print military time format
15 void printStandard(); // print standard time format
16 private:
17 int hour; // 0 - 23
18 int minute; // 0 - 59
19 int second; // 0 - 59
20 };
21
22 #endif
11-09-2022 68
23 // time1.cpp
24 // Member function definitions for Time class.
25 #include <iostream>
26
27 using std::cout;
28 Source file uses #include
29 #include "time1.h"
30
to load the header file
31 // Time constructor initializes each data member to zero.
32 // Ensures all Time objects start in a consistent state.
33 Time::Time() { hour = minute = second = 0; }
34
35 // Set a new Time value using military time. Perform validity
36 // checks on the data values. Set invalid values to zero.
37 void Time::setTime( int h, int m, int s )
38 {
39 hour = ( h >= 0 && h < 24 ) ? h : 0;
40 minute = ( m >= 0 && m < 60 ) ? m : 0;
41 second = ( s >= 0 && s < 60 ) ? s : 0; Source file contains
42 }
43
function definitions
44 // Print Time in military format
45 void Time::printMilitary()
46 {
47 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
48 << ( minute < 10 ? "0" : "" ) << minute;
49 }
50
51 // Print time in standard format
52 void Time::printStandard()
53 {
54 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
55 << ":" << ( minute < 10 ? "0" : "" ) << minute
56 << ":" << ( second < 10 ? "0" : "" ) << second
11-09-202257 << ( hour < 12 ? " AM" : " PM" ); 69
58 }
Controlling Access to Members
• public
• Presents clients with a view of the services the class
provides (interface)
• Data and member functions are accessible
• private
• Default access mode
• Data only accessible to member functions and
friends
• private members only accessible through the
public class interface using public member
functions
11-09-2022 70
1 // 06.cpp
2 // Demonstrate errors resulting from attempts
3 // to access private class members.
4 #include <iostream>
5
6 using std::cout;
7
8 #include "time1.h"
9
10 int main()
11 {
12 Time t;
13
14 // Error: 'Time::hour' is not accessible
15 t.hour = 7; Attempt to modify private member
16 variable hour.
17 // Error: 'Time::minute' is not accessible
18 cout << "minute = " << t.minute;
19 Attempt to access private member
20 return 0; variable minute.
21 }
Compiling...
Fig06_06.cpp
D:\Fig06_06.cpp(15) : error C2248: 'hour' : cannot access private
member declared in class 'Time'
D:\Fig6_06\time1.h(18) : see declaration of 'hour'
D:\Fig06_06.cpp(18) : error C2248: 'minute' : cannot access private
member declared in class 'Time'
D:\time1.h(19) : see declaration of 'minute'
Error executing cl.exe.
11-09-2022 71
test.exe - 2 error(s), 0 warning(s)
Access Functions and Utility Functions
• Utility functions
• private functions that support the operation of
public functions
• Not intended to be used directly by clients
• Access functions
• public functions that read/display data or check
conditions
• Allow public functions to check private data
• Following example
• Program to take in monthly sales and output the total
• Implementation not shown, only access functions
11-09-2022 72
87 // _07.cpp
88 // Demonstrating a utility function
89 // Compile with salesp.cpp
90 #include "salesp.h"
Create object s, an instance
91
of class SalesPerson
92 int main()
93 {
94 SalesPerson s; // create SalesPerson object s
95
96 s.getSalesFromUser(); // note simple sequential code
97 s.printAnnualSales(); // no control structures in main
98 return 0;
99 }
OUTPUT
Enter sales amount for month 1: 5314.76
Enter sales amount for month 2: 4292.38
Enter sales amount for month 3: 4589.83
Enter sales amount for month 4: 5534.03
Enter sales amount for month 5: 4376.34
Enter sales amount for month 6: 5698.45
Enter sales amount for month 7: 4439.22
Enter sales amount for month 8: 5893.57
Enter sales amount for month 9: 4909.67
Enter sales amount for month 10: 5123.45
Enter sales amount for month 11: 4024.97
Enter sales amount for month 12: 5923.92
11-09-2022 73
Class definition
class class_name {
public:
constructor and destructor
member functions
private:
data members
};
11-09-2022 74
Initializing Class Objects: Constructors
• Constructors
• Initialize class members
• Same name as the class
• No return type
• Member variables can be initialized by the constructor or
set afterwards
• Passing arguments to a constructor
• When an object of a class is declared, initializers can be
provided
• Format of declaration with initializers:
Class-type ObjectName( value1,value2,…);
• Default arguments may also be specified in the
constructor prototype
11-09-2022 75
1 // time2.h
2 // Declaration of the Time class.
3 // Member functions are defined in time2.cpp
4
5 // preprocessor directives that
6 // prevent multiple inclusions of header file
7 #ifndef TIME2_H
8 #define TIME2_H
9
10 // Time abstract data type definition
11 class Time {
12 public:
13 Time( int = 0, int = 0, int = 0 ); // default constructor
14 void setTime( int, int, int ); // set hour, minute, second
15 void printMilitary(); // print military time format
16 void printStandard(); // print standard time format
17 private:
18 int hour; // 0 - 23
19 int minute; // 0 - 59
20 int second; // 0 - 59
21 };
22
23 #endif
11-09-2022 76
61 //8.cpp
62 // Demonstrating a default constructor
63 // function for class Time.
64 #include <iostream>
65
66 using std::cout;
67 using std::endl;
68
69 #include "time2.h"
70
71 int main()
72 {
73 Time t1, // all arguments defaulted
74 t2(2), // minute and second defaulted
75 t3(21, 34), // second defaulted
76 t4(12, 25, 42), // all values specified
77 t5(27, 74, 99); // all bad values specified
78
79 cout << "Constructed with:\n"
80 << "all arguments defaulted:\n ";
81 t1.printMilitary();
82 cout << "\n ";
83 t1.printStandard();
84
85 cout << "\nhour specified; minute and second defaulted:"
86 << "\n ";
87 t2.printMilitary();
88 cout << "\n ";
89 t2.printStandard();
90
91 cout << "\nhour and minute specified; second defaulted:"
11-09-202292 << "\n "; 77
93 t3.printMilitary();
94 cout << "\n ";
95 t3.printStandard();
96
97 cout << "\nhour, minute, and second specified:"
98 << "\n ";
99 t4.printMilitary();
100 cout << "\n ";
101 t4.printStandard();
102
103 cout << "\nall invalid values specified:"
104 << "\n ";
105 t5.printMilitary();
106 cout << "\n ";
107 t5.printStandard();
108 cout << endl;
109
110 return 0;
111 }
OUTPUT
When only hour
Constructed with:
all arguments defaulted: is specified,
00:00 minute and
12:00:00 AM
second are set
hour specified; minute and second defaulted:
02:00 to their default
2:00:00 AM values of 0.
hour and minute specified; second defaulted:
21:34
9:34:00 PM
hour, minute, and second specified:
12:25
12:25:42 PM
all invalid values specified:
11-09-2022 00:00 78
12:00:00 AM
Using Destructors
• Destructors
• Are member function of class
• Perform termination housekeeping before the system
reclaims the object’s memory
• Complement of the constructor
• Name is tilde (~) followed by the class name (i.e.,
~Time)
• Recall that the constructor’s name is the class name
• Receives no parameters, returns no value
• One destructor per class
• No overloading allowed
11-09-2022 79
When Constructors and Destructors Are Called
• Constructors and destructors called automatically
• Order depends on scope of objects
• Global scope objects
• Constructors called before any other function (including main)
• Destructors called when main terminates (or exit function
called)
• Destructors not called if program terminates with abort
• Automatic local objects
• Constructors called when objects are defined
• Destructors called when objects leave scope
• i.e., when the block in which they are defined is exited
• Destructors not called if the program ends with exit or abort
11-09-2022 80
When Constructors and Destructors Are Called
11-09-2022 81
1 //9: create.h
2 // Definition of class CreateAndDestroy.
3 // Member functions defined in create.cpp.
4 #ifndef CREATE_H
5 #define CREATE_H
6
7 class CreateAndDestroy {
8 public:
9 CreateAndDestroy( int ); // constructor
10 ~CreateAndDestroy(); // destructor
11 private:
12 int data;
13 };
14
15 #endif
11-09-2022 82
16 // 9: create.cpp
18 #include <iostream>
19
20 using std::cout;
21 using std::endl;
22
23 #include "create.h"
24
29 }
30
31 CreateAndDestroy::~CreateAndDestroy()
32 { cout << "Object " << data << " destructor " << endl; }
11-09-2022 83
33 // 09.cpp
34 // Demonstrating the order in which constructors and
35 // destructors are called.
36 #include <iostream>
37
38 using std::cout;
39 using std::endl;
40
41 #include "create.h"
42
43 void create( void ); // prototype
44
45 CreateAndDestroy first( 1 ); // global object
46
47 int main()
48 {
49 cout << " (global created before main)" << endl;
50
51 CreateAndDestroy second( 2 ); // local object
52 cout << " (local automatic in main)" << endl;
53
54 static CreateAndDestroy third( 3 ); // local object
55 cout << " (local static in main)" << endl;
56
57 create(); // call function to create objects
58
59 CreateAndDestroy fourth( 4 ); // local object
60 cout << " (local automatic in main)" << endl;
11-09-202261 return 0; 84
62 }
63
64 // Function to create objects
65 void create( void )
66 {
67 CreateAndDestroy fifth( 5 );
68 cout << " (local automatic in create)" << endl;
69
70 static CreateAndDestroy sixth( 6 );
71 cout << " (local static in create)" << endl;
72
73 CreateAndDestroy seventh( 7 );
74 cout << " (local automatic in create)" << endl;
75 }
OUTPUT
Object 1 constructor (global created before main)
Object 2 constructor (local automatic in main)
Object 3 constructor (local static in main)
Object 5 constructor (local automatic in create)
Object 6 constructor (local static in create)
Object 7 constructor (local automatic in create)
Object 7 destructor
Object 5 destructor Notice how the order of the
Object 4 constructor (local automatic in main)
Object 4 destructor
Program Output constructor and destructor call
Object 2 destructor depends on the types of variables
Object 6 destructor (automatic, global and static)
Object 3 destructor
Object 1 destructor
they are associated with.
11-09-2022 85
Using Data Members and Member
Functions
• Member functions
• Allow clients of the class to set (i.e., write) or get (i.e., read)
the values of private data members
• Example:
Adjusting a customer’s bank balance
• private data member balance of a class BankAccount
could be modified through the use of member function
computeInterest
• A member function that sets data member interestRate could
be called setInterestRate, and a member function that
returns the interestRate could be called
getInterestRate
• Providing set and get functions does not make private
variables public
• A set function should ensure that the new value is valid
11-09-2022 86
A Subtle Trap: Returning a Reference to
a Private Data Member
• Reference to an object
• Alias for the name of the object
• May be used on the left side of an assignment
statement
• Reference can receive a value, which changes the
original object as well
• Returning references
• public member functions can return non-const
references to private data members
• Should be avoided, breaks encapsulation
11-09-2022 87
1 // time4.h
2 // Declaration of the Time class.
3 // Member functions defined in time4.cpp
4
5 // preprocessor directives that
6 // prevent multiple inclusions of header file
Notice how member function
7 #ifndef TIME4_H
badSetHour returns a reference
8 #define TIME4_H
(int & is the return type).
9
10 class Time {
11 public:
12 Time( int = 0, int = 0, int = 0 );
13 void setTime( int, int, int );
14 int getHour();
15 int &badSetHour( int ); // DANGEROUS reference return
16 private:
17 int hour;
18 int minute;
19 int second;
20 };
21
22 #endif
11-09-2022 88
23 // time4.cpp
24 // Member function definitions for Time class.
25 #include "time4.h"
26
27 // Constructor function to initialize private data.
28 // Calls member function setTime to set variables.
29 // Default values are 0 (see class definition).
30 Time::Time( int hr, int min, int sec )
31 { setTime( hr, min, sec ); }
32
33 // Set the values of hour, minute, and second.
34 void Time::setTime( int h, int m, int s )
35 {
36 hour = ( h >= 0 && h < 24 ) ? h : 0;
37 minute = ( m >= 0 && m < 60 ) ? m : 0;
38 second = ( s >= 0 && s < 60 ) ? s : 0;
39 }
40
41 // Get the hour value 1. Load header
42 int Time::getHour() { return hour; }
badSetHour returns a
43
reference to the
44
45 1.1 Function definitions
// POOR PROGRAMMING PRACTICE:
// Returning a reference to a private data member. private member
46 int &Time::badSetHour( int hh ) variable hour. Changing
47 { this reference will alter
48 hour = ( hh >= 0 && hh < 24 ) ? hh : 0; hour as well.
49
50 return hour; // DANGEROUS reference return
11-09-202251 } 89
52 //11.cpp
53 // Demonstrating a public member function that
54 // returns a reference to a private data member.
55 // Time class has been trimmed for this example.
56 #include <iostream>
57
58 using std::cout;
59 using std::endl;
60
61 #include "time4.h"
62
63 int main()
64 {
65 Time t;
66 int &hourRef = t.badSetHour( 20 );
67
68 cout << "Hour before modification: " << hourRef;
69 hourRef = 30; // modification with invalid value
70 cout << "\nHour after modification: " << t.getHour();
71 Hour after modification: 30
72 // Dangerous: Function call that returns
73 // a reference can be used as an lvalue!
74 t.badSetHour(12) = 74;
75 cout << "\n\n*********************************\n"
76 << "POOR PROGRAMMING PRACTICE!!!!!!!!\n"
77 << "badSetHour as an lvalue, Hour: "
78 << t.getHour() *********************************
79 << "\n*********************************" << endl;
80 POOR PROGRAMMING PRACTICE!!!!!!!!
81 return 0; badSetHour as an lvalue, Hour: 74
11-09-2022 82 } ********************************* 90
Hour before modification: 20
Hour after modification: 30
*********************************
POOR PROGRAMMING PRACTICE!!!!!!!!
badSetHour as an lvalue, Hour: 74
*********************************
Program Output
11-09-2022 91
Assignment by Default Memberwise
Copy
• Assigning objects
• An object can be assigned to another object of the
same type using the assignment operator (=)
• Member by member copy
• Objects may be
• Passed as function arguments
• Returned from functions (call-by-value default)
11-09-2022 92
1 //12.cpp
2 // Demonstrating that class objects can be assigned
3 // to each other using default memberwise copy
4 #include <iostream>
5
6 using std::cout;
7 using std::endl;
8
9 // Simple Date class
10 class Date {
11 public:
12 Date( int = 1, int = 1, int = 1990 ); // default constructor
13 void print();
14 private:
15 int month;
16 int day;
17 int year;
18 };
19
20 // Simple Date constructor with no range checking
21 Date::Date( int m, int d, int y )
22 {
23 month = m;
24 day = d;
25 year = y;
26 }
27
28 // Print the Date in the form mm-dd-yyyy
29 void Date::print()
30 { cout << month << '-' << day << '-' << year; }
11-09-2022 93
31
32 int main()
33 {
34 Date date1( 7, 4, 1993 ), date2; // d2 defaults to 1/1/90
35
36 cout << "date1 = ";
37 date1.print();
38 cout << "\ndate2 = ";
39 date2.print();
40
41 date2 = date1; // assignment by default memberwise copy
42 cout << "\n\nAfter default memberwise copy, date2 = ";
43 date2.print();
44 cout << endl;
45
46 return 0;
47 }
date1 = 7-4-1993
date2 = 1-1-1990
11-09-2022 94
Software Reusability
• Software resusability
• Implementation of useful classes
• Class libraries exist to promote reusability
• Allows for construction of programs from existing, well-defined, carefully
tested, well-documented, portable, widely available components
• Speeds development of powerful, high-quality software
11-09-2022 95
Objectives
11-09-2022 96
Inheritance
• Allows code re-use : Fine in theory – requires good design
• Use when relationship between classes is
• “Kind of” or “is a”
• Create class hierarchies
• Factor out common attributes and behaviour
• Place common features in base class
• Differences in separate derived classes
11-09-2022 97
Example Class Hierarchy
11-09-2022 98
Class hierarchies
• Class at top of hierarchy is most abstract
• Classes become more “specialised” or “concrete” as we go down the class
hierarchy.
• Often we will only create real objects of the lowest classes in the hierarchy not
the classes at or near the top of the hierarchy.
• In C++ we can prohibit the creation of objects of the base classes by making the
class an “abstract class”
11-09-2022 99
Inheritance in C++
• Terminology
• Base class (super class or parent
class) Base
11-09-2022 100
Inheritance in C++
11-09-2022 102
Public inheritance
Public Base
functions
Public
Base object
functions
Private
Derived
Derived object Interface
11-09-2022 103
Compare with Composition
Public
Base Interface
functions
object
Private
Private
11-09-2022 104
The Derived class
• The constructor function of the derived class should invoke the
constructor of the class from which it has been derived.
• Use the initialiser list of the derived constructor to invoke the base
class constructor.
• Base constructor invocation may be omitted iff the base class has a
default constructor which will be automatically invoked.
11-09-2022 105
Inheritance vs composition
• Use inheritance where the base interface is required to be available in derived
class either as is or with some functions overidden.
• Use composition when the base interface is not needed or needs to be
augmented or controlled by the enclosing class.
• Use composition when the enclosing class uses several objects of differing classes
• Given a choice use composition in preference to inheritance.
• Look for “has a” vs. “is a”
11-09-2022 106
class B
{
public: // constructor
B(int x) { privint = x; }
private:
int privint;
etc.
};
class D : public B
{
public: // constructor
D(float i, int j) : B(j) { privfloat = i;}
private:
float privfloat;
etc.
};
11-09-2022 107
Protected access specifier
• As well as public and private access specifiers we have protected access specifier.
• Protected access is an intermediate level between private and public.
• protected class members can only be accessed by the class and any derived
classes
• Guide - Still use private in preference to protected unless there is a good reason
not to.
11-09-2022 108
Multiple inheritance
11-09-2022 109
Advanced Topics on Inheritance
• Multiple inheritance allows a derived class to inherit
from more than one direct base class
class Bear: public ZooAnimal {/*...*/};
class Panda: public Bear, public Endangered {/*...*/};
11-09-2022 110
Single Inheritance
class A {
public: int main (int, char * []){
A(int num): aInt(num) { B b(2, 3);
cout << "A::constructor"<<endl;;} return 0;
~A() { }
cout <<"A::destructor"<<endl;}
protected:
A
int aInt;
}; Output:
A::constructor
class C: public B {
B::constructor
public:
C(int numa, int numb, string s )
C::constructor
: B(numa, numb), cStr(s) { C::destructor A
cout << "C::constructor"<<endl;} B::destructor
~C() { A::destructor
cout << "C::destructor"<<endl;} B
protected:
string cStr;
};
C
int main (int, char * []) {
C c(4, 7, "hello");
return 0;
}
11-09-2022 112
Multiple Inheritance
class X { class Z : public X, public Y {
public: public:
X(): xChar('D') {cout << "X::defaultZ(char xC,char yC, int num)
constructor"<<endl;;}
: X(xC), Y(yC), zInt(num) {
X(char c): xChar(c) {cout << cout << "Z::constructor"<<endl;}
"X::constructor"<<endl;;}
~Z() {
~X() {
cout << "Z::destructor"<<endl;}
cout << "X::destructor"<<endl;}
protected:
protected:
int zInt;
char xChar;
};
}; int main (int, char *[])) {
Z zObj('z', 'b', 8);
class Y { return 0; }
public:
X Y
Y(char c): yChar(c) { Output:
cout << "Y::constructor"<<endl;;} X::constructor
Y::constructor
~Y() {cout << "Y::destructor"<<endl;}
Z::constructor
protected: Z
Z::destructor
char yChar; Y::destructor
}; X::destructor
11-09-2022 113
Multiple Inheritance, continued
class MI: public C, public Z { int main (int, char * []) {
public: MI mi(2,4,"eve", 'r', 's', 26);
return 0;
MI(int numa, int numb, string s,
}
char xC, char yC, int numZ )
: C(numa, numb, s), Z(xC, yC, numZ) Output:
{cout << "MI::constructor"<<endl;}
~MI() {cout << A::constructor
"MI::destructor"<<endl;} B::constructor
protected: C::constructor
string cStr; X::constructor
Y::constructor
};
A Z::constructor
X Y
MI::constructor
MI::destructor
B Z::destructor
Y::destructor
Z X::destructor
C C::destructor
B::destructor
A::destructor
MI
11-09-2022 114
All Base Class Constructors are Called
// X and Y as declared previously int main (int, char * []) {
class R : public X, public Y { R r ('x', 'y', 8);
return 0;
public:
}
R(char xC, char yC, int numx): Y(yC), Output:
X(xC), rInt(numx) {cout << X::constructor
"R::constructor" << endl;} Y::constructor
~R() { R::constructor
R::destructor
cout << "R::destructor" <<endl;}
Y::destructor
protected: X::destructor
int rInt;
int main (int, char * []) {
};
S s('y', 10);
class S : public Y, public X { return 0;
public: }
Output:
S(char yC, int numx): Y(yC),
sInt(numx) {cout << Y::constructor
"S::constructor"<<endl;} X::default constructor
~S() {cout << "S::destructor"<<endl;} S::constructor
S::destructor
protected:
X::destructor
int sInt; Y::destructor
};
11-09-2022 115
Base Pointer/Reference Type Restricts Interface
Method Classes Declaring It Bear * bear_ptr =
new Panda ("bao_bao");
print Animal bear_ptr ->print(); // ok
Bear bear_ptr ->toes(); // ok
Endangered bear_ptr ->cuddle(); // not ok
Panda bear_ptr ->growl(); // not ok
Grizzly
delete bear_ptr; // ok
toes Bear
Panda
Endangered * endangered_ptr =
Grizzly
new Grizzly;
growl Grizzly
11-09-2022 117
More About Virtual Base Classes
• Still Polymorphic
• Can convert between uses as Derived vs. Base
11-09-2022 119
Introduction
• Inheritance
• New classes created from existing classes
• Absorb attributes and behaviors.
• Polymorphism
• Write programs in a general fashion
• Handle a wide variety of existing (and unspecified)
related classes
• Derived class
• Class that inherits data members and member
functions from a previously defined base class
11-09-2022 120
Introduction
• Inheritance
• Single Inheritance
• Class inherits from one base class
• Multiple Inheritance
• Class inherits from multiple base classes
• Three types of inheritance:
• public: Derived objects are accessible by the base class
objects (focus of this chapter)
• private: Derived objects are inaccessible by the base class
• protected: Derived classes and friends can access
protected members of the base class
11-09-2022 121
Base and Derived Classes
11-09-2022 122
Base and Derived Classes
11-09-2022 123
Base and Derived Classes
11-09-2022 124
Base and Derived Classes
11-09-2022 125
Protected Members
• protected inheritance
• Intermediate level of protection between public and
private inheritance
• Derived-class members can refer to public and
protected members of the base class simply by using the
member names
• Note that protected data “breaks” encapsulation
11-09-2022 126
Casting Base Class Pointers to Derived Class
Pointers
11-09-2022 127
Casting Base-Class Pointers to Derived-Class
Pointers
• Example
• Circle class derived from the Point base class
• We use pointer of type Point to reference a Circle
object, and vice-versa
11-09-2022 128
1 // Fig. 19.4: point.h
Outline
2 // Definition of class Point
3 #ifndef POINT_H
point.h
4 #define POINT_H
5
6 #include <iostream>
7
8 using std::ostream;
9
10 class Point {
11 friend ostream &operator<<( ostream &, const Point & );
12 public:
13 Point( int = 0, int = 0 ); // default constructor
14 void setPoint( int, int ); // set coordinates
15 int getX() const { return x; } // get x coordinate
16 int getY() const { return y; } // get y coordinate
17 protected: // accessible by derived classes
18 int x, y; // x and y coordinates of the Point
19 }; // end class Point
20
21 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
22 // Fig. 19.4: point.cpp
23 // Member functions for class Point Outline
24 #include <iostream>
25 #include "point.h"
26
point.cpp
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 )
32 {
33 x = a;
34 y = b;
35 } // end function setPoint
36
37 // Output Point (with overloaded stream insertion operator)
38 ostream &operator<<( ostream &output, const Point &p )
39 {
40 output << '[' << p.x << ", " << p.y << ']';
41
42 return output; // enables cascaded calls
43 } // end operator<< function
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
44 // Fig. 19.4: circle.h
45 // Definition of class Circle Outline
46 #ifndef CIRCLE_H
47 #define CIRCLE_H
48
circle.h
49 #include <iostream>
50
51 using std::ostream;
52
53 #include <iomanip>
54
55 using std::ios;
56 using std::setiosflags;
57 using std::setprecision;
58
59 #include "point.h"
60
61 class Circle : public Point { // Circle inherits from Point
62 friend ostream &operator<<( ostream &, const Circle & );
63 public:
64 // default constructor
65 Circle( double r = 0.0, int x = 0, int y = 0 );
66
67 void setRadius( double ); // set radius
68 double getRadius() const; // return radius
69 double area() const; // calculate area
70 protected:
71 double radius;
72 }; // end class Circle
73
74 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
75 // Fig. 19.4: circle.cpp
76 // Member function definitions for class Circle Outline
77 #include "circle.h"
78
79 // Constructor for Circle calls constructor for Point
circle.cpp
80 // with a member initializer then initializes radius.
81 Circle::Circle( double r, int a, int b )
82 : Point( a, b ) // call base-class constructor
83 { setRadius( r ); }
84
85 // Set radius of Circle
86 void Circle::setRadius( double r )
87 { radius = ( r >= 0 ? r : 0 ); }
88
89 // Get radius of Circle
90 double Circle::getRadius() const { return radius; }
91
92 // Calculate area of Circle
93 double Circle::area() const
94 { return 3.14159 * radius * radius; }
95
96 // Output a Circle in the form:
97 // Center = [x, y]; Radius = #.##
98 ostream &operator<<( ostream &output, const Circle &c )
99 {
100 output << "Center = " << static_cast< Point >( c )
101 << "; Radius = "
102 << setiosflags( ios::fixed | ios::showpoint )
103 << setprecision( 2 ) << c.radius;
104
105 return output; // enables cascaded calls
106 } // end operator<< function
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
107 // Fig. 19.4: fig19_04.cpp
108 // Casting base-class pointers to derived-class pointers Outline
109 #include <iostream>
110
111 using std::cout;
fig19_04.cpp (1 of 2)
112 using std::endl;
113
114 #include <iomanip>
115
116 #include "point.h"
117 #include "circle.h"
118
119 int main()
120 {
121 Point *pointPtr = 0, p( 30, 50 );
122 Circle *circlePtr = 0, c( 2.7, 120, 89 );
123
124 cout << "Point p: " << p << "\nCircle c: " << c << '\n';
125
126 // Treat a Circle as a Point (see only the base class part)
127 pointPtr = &c; // assign address of Circle to pointPtr
128 cout << "\nCircle c (via *pointPtr): "
129 << *pointPtr << '\n';
130
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
131 // Treat a Circle as a Circle (with some casting)
132 // cast base-class pointer to derived-class pointer Outline
133 circlePtr = static_cast< Circle * >( pointPtr );
134 cout << "\nCircle c (via *circlePtr):\n" << *circlePtr
135 << "\nArea of c (via circlePtr): "
fig19_04.cpp (2 of 2)
136 << circlePtr->area() << '\n';
137
138 // DANGEROUS: Treat a Point as a Circle
139 pointPtr = &p; // assign address of Point to pointPtr
140
141 // cast base-class pointer to derived-class pointer
142 circlePtr = static_cast< Circle * >( pointPtr );
143 cout << "\nPoint p (via *circlePtr):\n" << *circlePtr
144 << "\nArea of object circlePtr points to: "
145 << circlePtr->area() << endl;
146 return 0;
147 } // end function main
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
Using Member Functions
• Derived class
• Cannot directly access private members of its base class
• Hiding private members is a huge help in testing,
debugging and correctly modifying systems
11-09-2022 135
Overriding Base-Class Members in a Derived
Class
11-09-2022 136
1 // Fig. 19.5: employ.h
2 // Definition of class Employee Outline
3 #ifndef EMPLOY_H
4 #define EMPLOY_H
5
employ.h
6 class Employee {
7 public:
8 Employee( const char *, const char * ); // constructor
9 void print() const; // output first and last name
10 ~Employee(); // destructor
11 private:
12 char *firstName; // dynamically allocated string
13 char *lastName; // dynamically allocated string
14 }; // end class Employee
15
16 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
27 // Constructor dynamically allocates space for the
28 // first and last name and uses strcpy to copy Outline
29 // the first and last names into the object.
30 Employee::Employee( const char *first, const char *last )
31 {
employ.cpp (2 of 2)
32 firstName = new char[ strlen( first ) + 1 ];
33 assert( firstName != 0 ); // terminate if not allocated
34 strcpy( firstName, first );
35
36 lastName = new char[ strlen( last ) + 1 ];
37 assert( lastName != 0 ); // terminate if not allocated
38 strcpy( lastName, last );
39 } // end Employee constructor
40
41 // Output employee name
42 void Employee::print() const
43 { cout << firstName << ' ' << lastName; }
44
45 // Destructor deallocates dynamically allocated memory
46 Employee::~Employee()
47 {
48 delete [] firstName; // reclaim dynamic memory
49 delete [] lastName; // reclaim dynamic memory
50 } // end Employee destructor
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
51 // Fig. 19.5: hourly.h
52 // Definition of class HourlyWorker Outline
53 #ifndef HOURLY_H
54 #define HOURLY_H
55
hourly.h
56 #include "employ.h"
57
58 class HourlyWorker : public Employee {
59 public:
60 HourlyWorker( const char*, const char*, double, double );
61 double getPay() const; // calculate and return salary
62 void print() const; // overridden base-class print
63 private:
64 double wage; // wage per hour
65 double hours; // hours worked for week
66 }; // end class HourlyWorker
67
68 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
78 using std::ios;
79 using std::setiosflags; Outline
80 using std::setprecision;
81
82 #include "hourly.h"
hourly.cpp (2 of 2)
83
84 // Constructor for class HourlyWorker
85 HourlyWorker::HourlyWorker( const char *first,
86 const char *last,
87 double initHours, double initWage )
88 : Employee( first, last ) // call base-class constructor
89 {
90 hours = initHours; // should validate
91 wage = initWage; // should validate
92 } // end HourlyWorker constructor
93
94 // Get the HourlyWorker's pay
95 double HourlyWorker::getPay() const { return wage * hours; }
96
97 // Print the HourlyWorker's name and pay
98 void HourlyWorker::print() const
99 {
100 cout << "HourlyWorker::print() is executing\n\n";
101 Employee::print(); // call base-class print function
102
103 cout << " is an hourly worker with pay of $"
104 << setiosflags( ios::fixed | ios::showpoint )
105 << setprecision( 2 ) << getPay() << endl;
106 } // end function print
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
107 // Fig. 19.5: fig19_05.cpp
108 // Overriding a base-class member function in a Outline
109 // derived class.
110 #include "hourly.h"
111
fig19_05.cpp
112 int main()
113 {
114 HourlyWorker h( "Bob", "Smith", 40.0, 10.00 );
115 h.print();
116 return 0;
117 } // end function main
HourlyWorker::print() is executing
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
Public, Private, and Protected Inheritance
11-09-2022 142
Direct and Indirect Base Classes
11-09-2022 143
Using Constructors and Destructors in Derived
Classes
11-09-2022 144
Using Constructors and Destructors in Derived
Classes
• Derived-class constructor
• Calls the constructor for its base class first to initialize its
base-class members
• If the derived-class constructor is omitted, its default
constructor calls the base-class’ default constructor
• Destructors are called in the reverse order of
constructor calls.
• Derived-class destructor is called before its base-class
destructor
11-09-2022 145
1 // Fig. 19.7: point2.h
2 // Definition of class Point Outline
3 #ifndef POINT2_H
4 #define POINT2_H
5
point2.h
6 class Point {
7 public:
8 Point( int = 0, int = 0 ); // default constructor
9 ~Point(); // destructor
10 protected: // accessible by derived classes
11 int x, y; // x and y coordinates of Point
12 }; // end class Point
13
14 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
15 // Fig. 19.7: point2.cpp
16 // Member function definitions for class Point Outline
17 #include <iostream>
18
19 using std::cout;
point2.cpp
20 using std::endl;
21
22 #include "point2.h"
23
24 // Constructor for class Point
25 Point::Point( int a, int b )
26 {
27 x = a;
28 y = b;
29
30 cout << "Point constructor: "
31 << '[' << x << ", " << y << ']' << endl;
32 } // end Point constructor
33
34 // Destructor for class Point
35 Point::~Point()
36 {
37 cout << "Point destructor: "
38 << '[' << x << ", " << y << ']' << endl;
39 } // end Point destructor
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
40 // Fig. 19.7: circle2.h
41 // Definition of class Circle Outline
42 #ifndef CIRCLE2_H
43 #define CIRCLE2_H
44
circle2.h
45 #include "point2.h"
46
47 class Circle : public Point {
48 public:
49 // default constructor
50 Circle( double r = 0.0, int x = 0, int y = 0 );
51
52 ~Circle();
53 private:
54 double radius;
55 }; // end class Circle
56
57 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
58 // Fig. 19.7: circle2.cpp
59 // Member function definitions for class Circle Outline
60 #include <iostream>
61
62 using std::cout;
circle2.cpp
63 using std::endl;
64
65 #include "circle2.h"
66
67 // Constructor for Circle calls constructor for Point
68 Circle::Circle( double r, int a, int b )
69 : Point( a, b ) // call base-class constructor
70 {
71 radius = r; // should validate
72 cout << "Circle constructor: radius is "
73 << radius << " [" << x << ", " << y << ']' << endl;
74 } // end Circle constructor
75
76 // Destructor for class Circle
77 Circle::~Circle()
78 {
79 cout << "Circle destructor: radius is "
80 << radius << " [" << x << ", " << y << ']' << endl;
81 } // end Circle destructor
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
82 // Fig. 19.7: fig19_07.cpp
83 // Demonstrate when base-class and derived-class Outline
84 // constructors and destructors are called.
85 #include <iostream>
86
fig19_07.cpp (1 of 2)
87 using std::cout;
88 using std::endl;
89
90 #include "point2.h"
91 #include "circle2.h"
92
93 int main()
94 {
95 // Show constructor and destructor calls for Point
96 {
97 Point p( 11, 22 );
98 } // end block
99
100 cout << endl;
101 Circle circle1( 4.5, 72, 29 );
102 cout << endl;
103 Circle circle2( 10, 5, 5 );
104 cout << endl;
105 return 0;
106 } // end function main
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
Point constructor: [11, 22]
Point destructor: [11, 22] Outline
Point constructor: [72, 29]
Circle constructor: radius is 4.5 [72, 29] fig19_07.cpp (2 of 2)
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
Implicit Derived-Class Object to Base-Class
Object Conversion
• baseClassObject = derivedClassObject;
• This will work
• Remember, the derived class object has more members than the
base class object
• Extra data is not given to the base class
• derivedClassObject = baseClassObject;
• May not work properly
• Unless an assignment operator is overloaded in the derived class,
data members exclusive to the derived class will be unassigned
• Base class has less data members than the derived class
• Some data members missing in the derived class object
11-09-2022 152
Implicit Derived-Class Object to Base-Class
Object Conversion
11-09-2022 154
Composition vs. Inheritance
11-09-2022 155
Uses A And Knows A Relationships
• “uses a” relationship
• One object issues a function call to a member function of
another object
• “knows a” relationship
• One object is aware of another
• Contains a pointer handle or reference handle to another
object
• Also called an association
11-09-2022 156
Operator overloading
11-09-2022 157
Why Operator Overloading
int i, j, k; // integers
float m, n, p; // floats The compiler overloads
the + operator for built-in
integer and float types by
k = i + j; default, producing integer
// integer addition and assignment addition with i+j, and
p = m + n; floating addition with m+n.
// floating addition and assignment
operator@(argument-list) operator-
operator*
operator/
--- operator is a function
--- @ is one of C++ operator symbols (+, -, =, etc..)
11-09-2022 159
Example of Operator Overloading
class CStr
{
char *pData; void CStr::cat(char *s)
int nLength; {
public: int n;
// … char *pTemp;
void cat(char *s); n=strlen(s);
// … if (n==0) return;
CStr operator+(CStr str1, CStr str2);
CStr operator+(CStr str, char *s); pTemp=new char[n+nLength+1];
CStr operator+(char *s, CStr str); if (pData)
strcpy(pTemp,pData);
//accessors
char* get_Data(); strcat(pTemp,s);
int get_Len(); pData=pTemp;
nLength+=n;
}; }
11-09-2022 160
The Addition (+) Operator
CStr CStr::operator+(CStr str1, CStr str2)
{
CStr new_string(str1);
//call the copy constructor to initialize an
//entirely new CStr object with the first
//operand
new_string.cat(str2.get_Data());
//concatenate the second operand onto the
//end of new_string
return new_string;
//call copy constructor to create a copy of
//the return value new_string
}
new_string
str1
strcat(str1,str2)
strlen(str1)
strlen(str1)+strlen(str2)
11-09-2022 161
How does it work?
CStr first(“John”);
CStr last(“Johnson”);
CStr name(first+last);
11-09-2022 162
Implementing Operator Overloading
• Two ways:
• Implemented as member functions
• Implemented as non-member or Friend functions
• the operator function may need to be declared as a friend if it requires
access to protected or private data
11-09-2022 163
Implementing Operator Overloading
11-09-2022 167
What is ‘Friend’?
• Friend declarations introduce extra coupling between
classes
• Once an object is declared as a friend, it has access to all
non-public members as if they were public
• Access is unidirectional
• If B is designated as friend of A, B can access A’s non-public
members; A cannot access B’s
11-09-2022 168
More about ‘Friend’
• The major use of friends is
• to provide more efficient access to data members than
the function call
• to accommodate operator functions with easy access to
private data members
• Friends can have access to everything, which
defeats data hiding, so use them carefully
• Friends have permission to change the internal
state from outside the class. Always recommend
use member functions instead of friends to change
state
11-09-2022 169
Assignment Operator
• Assignment between objects of the same type is always
supported
• the compiler supplies a hidden assignment function if you don’t write
your own one
• same problem as with the copy constructor - the member by member
copying
• Syntax:
11-09-2022 170
Example: Assignment for CStr class
Assignment operator for CStr:
CStr& CStr::operator=(const CStr & source)
Return type - a reference to Argument type - a reference to a CStr object
(address of) a CStr object (since it is const, the function cannot modify it)
CStr object
(*this)
11-09-2022 172
Overloading stream-insertion and
stream-extraction operators
• In fact, cout<< or cin>> are operator overloading built in C++ standard
lib of iostream.h, using operator "<<" and ">>"
• cout and cin are the objects of ostream and istream classes,
respectively
• We can add a friend function which overloads the operator <<
friend ostream& operator<< (ostream &os, const Date &d);
11-09-2022 174
Learning Objectives
• Virtual Function Basics
• Late binding
• Implementing virtual functions
• When to use a virtual function
• Abstract classes and pure virtual functions
• Pointers and Virtual Functions
• Extended type compatibility
• Downcasting and upcasting
• C++ "under the hood" with virtual functions
11-09-2022 15-175
Virtual Function Basics
• Polymorphism
• Associating many meanings to one function
• Virtual functions provide this capability
• Fundamental principle of object-oriented
programming!
• Virtual
• Existing in "essence" though not in fact
• Virtual Function
• Can be "used" before it’s "defined"
11-09-2022 15-176
Figures Example
• Best explained by example:
• Classes for several kinds of figures
• Rectangles, circles, ovals, etc.
• Each figure an object of different class
• Rectangle data: height, width, center point
• Circle data: center point, radius
• All derive from one parent-class: Figure
• Require function: draw()
• Different instructions for each figure
11-09-2022 15-177
Figures Example 2
• Each class needs different draw function
• Can be called "draw" in each class, so:
Rectangle r;
Circle c;
r.draw(); //Calls Rectangle class’s draw
c.draw(); //Calls Circle class’s draw
• Nothing new here yet…
11-09-2022 15-178
Figures Example: center()
• Parent class Figure contains functions
that apply to "all" figures; consider:
center(): moves a figure to center of screen
• Erases 1st, then re-draws
• So Figure::center() would use function draw()
to re-draw
• Complications!
• Which draw() function?
• From which class?
11-09-2022 15-179
Figures Example: New Figure
• Consider new kind of figure comes along:
Triangle class
derived from Figure class
• Function center() inherited from Figure
• Will it work for triangles?
• It uses draw(), which is different for each figure!
• It will use Figure::draw() won’t work for triangles
• Want inherited function center() to use function
Triangle::draw() NOT function Figure::draw()
• But class Triangle wasn’t even WRITTEN when
Figure::center() was! Doesn’t know "triangles"!
11-09-2022 15-180
Figures Example: Virtual!
• Virtual functions are the answer
• Tells compiler:
• "Don’t know how function is implemented"
• "Wait until used in program"
• "Then get implementation from object
instance"
• Called late binding or dynamic binding
• Virtual functions implement late binding
11-09-2022 15-181
Virtual Functions: Another Example
11-09-2022 15-182
Virtual Functions: Auto Parts
• Program must:
• Compute daily gross sales
• Calculate largest/smallest sales of day
• Perhaps average sale for day
• All come from individual bills
• But many functions for computing bills will
be added "later"!
• When different types of sales added!
• So function for "computing a bill" will
be virtual!
11-09-2022 15-183
Class Sale Definition
• class Sale
{
public:
Sale();
Sale(double thePrice);
double getPrice() const;
virtual double bill() const;
double savings(const Sale& other) const;
private:
double price;
};
11-09-2022 15-184
Member Functions
savings and operator <
• double Sale::savings(const Sale& other) const
{
return (bill() – other.bill());
}
• bool operator < ( const Sale& first,
const Sale& second)
{
return (first.bill() < second.bill());
}
• Notice BOTH use member function bill()!
11-09-2022 15-185
Class Sale
• Represents sales of single item with no
added discounts or charges.
• Notice reserved word "virtual" in
declaration of member function bill
• Impact: Later, derived classes of Sale can
define THEIR versions of function bill
• Other member functions of Sale will use
version based on object of derived class!
• They won’t automatically use Sale’s version!
11-09-2022 15-186
Derived Class DiscountSale Defined
11-09-2022 15-187
DiscountSale’s Implementation
of bill()
• double DiscountSale::bill() const
{
double fraction = discount/100;
return (1 – fraction)*getPrice();
}
• Qualifier "virtual" does not go in actual
function definition
• "Automatically" virtual in derived class
• Declaration (in interface) not required to have
"virtual" keyword either (but usually does)
11-09-2022 15-188
DiscountSale’s Implementation
of bill()
• Virtual function in base class:
• "Automatically" virtual in derived class
• Derived class declaration (in interface)
• Not required to have "virtual" keyword
• But typically included anyway,
for readability
11-09-2022 15-189
Derived Class DiscountSale
• DiscountSale’s member function bill()
implemented differently than Sale’s
• Particular to "discounts"
• Member functions savings and "<"
• Will use this definition of bill() for all objects
of DiscountSale class!
• Instead of "defaulting" to version defined in
Sales class!
11-09-2022 15-190
Virtual: Wow!
• Recall class Sale written long before
derived class DiscountSale
• Members savings and "<" compiled before
even had ideas of a DiscountSale class
• Yet in a call like:
DiscountSale d1, d2;
d1.savings(d2);
• Call in savings() to function bill() knows to
use definition of bill() from DiscountSale class
• Powerful!
11-09-2022 15-191
Virtual: How?
• To write C++ programs:
• Assume it happens by "magic"!
• But explanation involves late binding
• Virtual functions implement late binding
• Tells compiler to "wait" until function is used in
program
• Decide which definition to use based on
calling object
• Very important OOP principle!
11-09-2022 15-192
Overriding
• Virtual function definition changed in a
derived class
• We say it’s been "overidden"
• Similar to redefined
• Recall: for standard functions
• So:
• Virtual functions changed: overridden
• Non-virtual functions changed: redefined
11-09-2022 15-193
Virtual Functions: Why Not All?
• Clear advantages to virtual functions as
we’ve seen
• One major disadvantage: overhead!
• Uses more storage
• Late binding is "on the fly", so programs run slower
• So if virtual functions not needed, should
not be used
11-09-2022 15-194
Pure Virtual Functions
• Base class might not have "meaningful"
definition for some of it’s members!
• It’s purpose solely for others to derive from
• Recall class Figure
• All figures are objects of derived classes
• Rectangles, circles, triangles, etc.
• Class Figure has no idea how to draw!
• Make it a pure virtual function:
virtual void draw() = 0;
11-09-2022 15-195
Abstract Base Classes
• Pure virtual functions require no definition
• Forces all derived classes to define "their
own" version
• Class with one or more pure virtual
functions is: abstract base class
• Can only be used as base class
• No objects can ever be created from it
• Since it doesn’t have complete "definitions" of all
it’s members!
• If derived class fails to define all pure’s:
• It’s an abstract base class too
11-09-2022 15-196
Extended Type Compatibility
• Given:
Derived is derived class of Base
• Derived objects can be assigned to objects
of type Base
• But NOT the other way!
• Consider previous example:
• A DiscountSale "is a" Sale, but reverse
not true
11-09-2022 15-197
Extended Type
Compatibility Example
• class Pet
{
public:
string name;
virtual void print() const;
};
class Dog : public Pet
{
public:
string breed;
virtual void print() const;
};
11-09-2022 15-198
Classes Pet and Dog
• Now given declarations:
Dog vdog;
Pet vpet;
• Notice member variables name and breed are public!
• For example purposes only! Not typical!
11-09-2022 15-199
Using Classes Pet and Dog
• Anything that "is a" dog "is a" pet:
• vdog.name = "Tiny";
vdog.breed = "Great Dane";
vpet = vdog;
• These are allowable
• Can assign values to parent-types, but
not reverse
• A pet "is not a" dog (not necessarily)
11-09-2022 15-200
Slicing Problem
• Notice value assigned to vpet "loses" it’s
breed field!
• cout << vpet.breed;
• Produces ERROR msg!
• Called slicing problem
• Might seem appropriate
• Dog was moved to Pet variable, so it should
be treated like a Pet
• And therefore not have "dog" properties
• Makes for interesting philosphical debate
11-09-2022 15-201
Slicing Problem Fix
• In C++, slicing problem is nuisance
• It still "is a" Great Dane named Tiny
• We’d like to refer to it’s breed even if it’s been treated as a Pet
• Can do so with pointers to
dynamic variables
11-09-2022 15-202
Slicing Problem Example
• Pet *ppet;
Dog *pdog;
pdog = new Dog;
pdog->name = "Tiny";
pdog->breed = "Great Dane";
ppet = pdog;
• Cannot access breed field of object
pointed to by ppet:
cout << ppet->breed; //ILLEGAL!
11-09-2022 15-203
Slicing Problem Example
• Must use virtual member function:
ppet->print();
• Calls print member function in Dog class!
• Because it’s virtual
• C++ "waits" to see what object pointer ppet is actually pointing to before
"binding" call
11-09-2022 15-204
Virtual Destructors
• Recall: destructors needed to de-allocate
dynamically allocated data
• Consider:
Base *pBase = new Derived;
…
delete pBase;
• Would call base class destructor even though
pointing to Derived class object!
• Making destructor virtual fixes this!
• Good policy for all destructors to be virtual
11-09-2022 15-205
Casting
• Consider:
Pet vpet;
Dog vdog;
…
vdog = static_cast<Dog>(vpet); //ILLEGAL!
• Can’t cast a pet to be a dog, but:
vpet = vdog; // Legal!
vpet = static_cast<Pet>(vdog); //Also legal!
• Upcasting is OK
• From descendant type to ancestor type
11-09-2022 15-206
Downcasting
• Downcasting dangerous!
• Casting from ancestor type to descended type
• Assumes information is "added"
• Can be done with dynamic_cast:
Pet *ppet;
ppet = new Dog;
Dog *pdog = dynamic_cast<Dog*>(ppet);
• Legal, but dangerous!
• Downcasting rarely done due to pitfalls
• Must track all information to be added
• All member functions must be virtual
11-09-2022 15-207
Inner Workings of Virtual Functions
11-09-2022 15-208
Summary 1
• Late binding delays decision of which
member function is called until runtime
• In C++, virtual functions use late binding
• Pure virtual functions have no definition
• Classes with at least one are abstract
• No objects can be created from
abstract class
• Used strictly as base for others to derive
11-09-2022 15-209
Summary 2
• Derived class objects can be assigned to
base class objects
• Base class members are lost; slicing problem
• Pointer assignments and dynamic objects
• Allow "fix" to slicing problem
• Make all destructors virtual
• Good programming practice
• Ensures memory correctly de-allocated
11-09-2022 15-210
11-09-2022 211
Case Study: Point, Circle, Cylinder
11-09-2022 212
1 // Fig. 19.8: point2.h
2 // Definition of class Point Outline
3 #ifndef POINT2_H
4 #define POINT2_H
5
point2.h
6 #include <iostream>
7
8 using std::ostream;
9
10 class Point {
11 friend ostream &operator<<( ostream &, const Point & );
12 public:
13 Point( int = 0, int = 0 ); // default constructor
14 void setPoint( int, int ); // set coordinates
15 int getX() const { return x; } // get x coordinate
16 int getY() const { return y; } // get y coordinate
17 protected: // accessible to derived classes
18 int x, y; // coordinates of the point
19 }; // end class Point
20
21 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
22 // Fig. 19.8: point2.cpp
23 // Member functions for class Point Outline
24 #include "point2.h"
25
26 // Constructor for class Point
point2.cpp
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 {
32 x = a;
33 y = b;
34 } // end function setPoint
35
36 // Output the Point
37 ostream &operator<<( ostream &output, const Point &p )
38 {
39 output << '[' << p.x << ", " << p.y << ']';
40
41 return output; // enables cascading
42 } // end operator<< function
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
43 // Fig. 19.8: fig19_08.cpp
44 // Driver for class Point Outline
45 #include <iostream>
46
47 using std::cout;
fig19_08.cpp
48 using std::endl;
49
50 #include "point2.h"
51
52 int main()
53 {
54 Point p( 72, 115 ); // instantiate Point object p
55
56 // protected data of Point inaccessible to main
57 cout << "X coordinate is " << p.getX()
58 << "\nY coordinate is " << p.getY();
59
60 p.setPoint( 10, 10 );
61 cout << "\n\nThe new location of p is " << p << endl;
62
63 return 0;
64 } // end function main
X coordinate is 72
Y coordinate is 115
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
1 // Fig. 19.9: circle2.h
2 // Definition of class Circle Outline
3 #ifndef CIRCLE2_H
4 #define CIRCLE2_H
5
circle2.h
6 #include <iostream>
7
8 using std::ostream;
9
10 #include "point2.h"
11
12 class Circle : public Point {
13 friend ostream &operator<<( ostream &, const Circle & );
14 public:
15 // default constructor
16 Circle( double r = 0.0, int x = 0, int y = 0 );
17 void setRadius( double ); // set radius
18 double getRadius() const; // return radius
19 double area() const; // calculate area
20 protected: // accessible to derived classes
21 double radius; // radius of the Circle
22 }; // end class Circle
23
24 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
25 // Fig. 19.9: circle2.cpp
26 // Member function definitions for class Circle Outline
27 #include <iomanip>
28
29 using std::ios;
circle2.cpp (1 of 2)
30 using std::setiosflags;
31 using std::setprecision;
32
33 #include "circle2.h"
34
35 // Constructor for Circle calls constructor for Point
36 // with a member initializer and initializes radius
37 Circle::Circle( double r, int a, int b )
38 : Point( a, b ) // call base-class constructor
39 { setRadius( r ); }
40
41 // Set radius
42 void Circle::setRadius( double r )
43 { radius = ( r >= 0 ? r : 0 ); }
44
45 // Get radius
46 double Circle::getRadius() const { return radius; }
47
48 // Calculate area of Circle
49 double Circle::area() const
50 { return 3.14159 * radius * radius; }
51
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
52 // Output a circle in the form:
53 // Center = [x, y]; Radius = #.## Outline
54 ostream &operator<<( ostream &output, const Circle &c )
55 {
56 output << "Center = " << static_cast< Point > ( c )
circle2.cpp (2 of 2)
57 << "; Radius = "
58 << setiosflags( ios::fixed | ios::showpoint )
59 << setprecision( 2 ) << c.radius;
60
61 return output; // enables cascaded calls
62 } // end operator<< function
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
73 int main()
74 { Outline
75 Circle c( 2.5, 37, 43 );
76
77 cout << "X coordinate is " << c.getX()
fig19_09.cpp (2 of 2)
78 << "\nY coordinate is " << c.getY()
79 << "\nRadius is " << c.getRadius();
80
81 c.setRadius( 4.25 );
82 c.setPoint( 2, 2 );
83 cout << "\n\nThe new location and radius of c are\n"
84 << c << "\nArea " << c.area() << '\n';
85
86 Point &pRef = c;
87 cout << "\nCircle printed as a Point is: " << pRef << endl;
88
89 return 0;
90 } // end function main
X coordinate is 37
Y coordinate is 43
Radius is 2.5
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
1 // Fig. 19.10: cylindr2.h
2 // Definition of class Cylinder Outline
3 #ifndef CYLINDR2_H
4 #define CYLINDR2_H
5
cylindr2.h
6 #include <iostream>
7
8 using std::ostream;
9
10 #include "circle2.h"
11
12 class Cylinder : public Circle {
13 friend ostream &operator<<( ostream &, const Cylinder & );
14
15 public:
16 // default constructor
17 Cylinder( double h = 0.0, double r = 0.0,
18 int x = 0, int y = 0 );
19
20 void setHeight( double ); // set height
21 double getHeight() const; // return height
22 double area() const; // calculate and return area
23 double volume() const; // calculate and return volume
24
25 protected:
26 double height; // height of the Cylinder
27 }; // end class Cylinder
28
29 #endif
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
30 // Fig. 19.10: cylindr2.cpp
31 // Member and friend function definitions Outline
32 // for class Cylinder.
33 #include "cylindr2.h"
34
cylindr2.cpp (1 of 2)
35 // Cylinder constructor calls Circle constructor
36 Cylinder::Cylinder( double h, double r, int x, int y )
37 : Circle( r, x, y ) // call base-class constructor
38 { setHeight( h ); }
39
40 // Set height of Cylinder
41 void Cylinder::setHeight( double h )
42 { height = ( h >= 0 ? h : 0 ); }
43
44 // Get height of Cylinder
45 double Cylinder::getHeight() const { return height; }
46
47 // Calculate area of Cylinder (i.e., surface area)
48 double Cylinder::area() const
49 {
50 return 2 * Circle::area() +
51 2 * 3.14159 * radius * height;
52 } // end function area
53
54 // Calculate volume of Cylinder
55 double Cylinder::volume() const
56 { return Circle::area() * height; }
57
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
58 // Output Cylinder dimensions
59 ostream &operator<<( ostream &output, const Cylinder &c ) Outline
60 {
61 output << static_cast< Circle >( c )
62 << "; Height = " << c.height;
cylindr2.cpp (2 of 2)
63
64 return output; // enables cascaded calls
65 } // end operator<< function
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
82 // use get functions to display the Cylinder
83 cout << "X coordinate is " << cyl.getX() Outline
84 << "\nY coordinate is " << cyl.getY()
85 << "\nRadius is " << cyl.getRadius()
86 << "\nHeight is " << cyl.getHeight() << "\n\n";
fig19_10.cpp (2 of 3)
87
88 // use set functions to change the Cylinder's attributes
89 cyl.setHeight( 10 );
90 cyl.setRadius( 4.25 );
91 cyl.setPoint( 2, 2 );
92 cout << "The new location, radius, and height of cyl are:\n"
93 << cyl << '\n';
94
95 cout << "The area of cyl is:\n"
96 << cyl.area() << '\n';
97
98 // display the Cylinder as a Point
99 Point &pRef = cyl; // pRef "thinks" it is a Point
100 cout << "\nCylinder printed as a Point is: "
101 << pRef << "\n\n";
102
103 // display the Cylinder as a Circle
104 Circle &circleRef = cyl; // circleRef thinks it is a Circle
105 cout << "Cylinder printed as a Circle is:\n" << circleRef
106 << "\nArea: " << circleRef.area() << endl;
107
108 return 0;
109 } // end function main
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights
X coordinate is 12
Y coordinate is 23 Outline
Radius is 2.5
Height is 5.7
fig19_10.cpp (3 of 3)
The new location, radius, and height of cyl are:
Center = [2, 2]; Radius = 4.25; Height = 10.00
The area of cyl is:
380.53
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights