Day4.1 OOP
Day4.1 OOP
Programming in C++
1
Abstract Data Types
• Are programmer-created data types that
specify
– the legal values that can be stored
– the operations that can be done on the values
• The user of an abstract data type (ADT) does
not need to know any implementation details
(e.g., how the data is stored or how the operations
on it are carried out)
2
Abstraction
• Abstraction allows a programmer to design a solution
to a problem and to use data items without concern
for how the data items are implemented
• This has already been encountered in the book:
– To use the pow function, you need to know what
inputs it expects and what kind of results it produces
– You do not need to know how it works
3
Abstraction and Data
Types
• Abstraction: a definition that captures general
characteristics without details
ex: An abstract triangle is a 3-sided polygon. A
specific triangle may be scalene, isosceles, or
equilateral
4
Object-Oriented
Programming
• Procedural programming focuses on the
processes/ actions that occur in a program.
Data and functions are separate and distinct.
• Object-oriented programming is based on
objects that encapsulate the data and the
functions that operate with and on the data.
5
Limitations of Procedural
Programming
6
OOP Terminology
• class: similar to a struct
– Allows bundling of related variables (member data)
and the functions that operate on them (member
functions)
– Describes the properties that all instances of the
class will have
• object: an instance of a class, in the same way that
a variable can be an instance of a struct
7
16.1
Inheritance Basics
• Inheritance is the process by which a new class,
called a derived class, is created from another
class, called the base class
– A derived class automatically has all the member
variables and functions of the base class
– A derived class can have additional member variables
and/or member functions
– The derived class is a child of the base or parent
class
8
Employee Classes
• To design a record-keeping program with
records for salaried and hourly employees…
– Salaried and hourly employees belong to a class
of people who share the property "employee"
– A subset of employees are those with a fixed wage
– Another subset of employees earn hourly wages
• All employees have a name and SSN
– Functions to manipulate name and SSN are the same
for hourly and salaried employees
9
A Base Class
• We will define a class called Employee for all
employees
• The Employee class will be used to define
classes for hourly and salaried employees
10
Function print_check
• Function print_check will have different
definitions to print different checks for each
type
of employee
– An Employee object lacks sufficient information to
print a check
– Each derived class will have sufficient information
to print a check
11
Class HourlyEmployee
• HourlyEmployee is derived from Class
Employee
– HourlyEmployee inherits all member functions
and
member variables of Employee
– The class definition begins
class HourlyEmployee : public Employee
• :public Employee shows that HourlyEmployee is
derived from class Employee
– HourlyEmployee declares additional member
variables wage_rate and hours
12
Inherited Members
• A derived class inherits all the members of the
parent class
– The derived class does not re-declare or re-define
members inherited from the parent, except…
– The derived class re-declares and re-defines
member functions of the parent class that will
have a different definition in the derived class
– The derived class can add member variables and
functions
13
Derived Class
• Any member functions added in the derived
class are defined in the implementation file
for
the derived class
– Definitions are not given for inherited functions
that are not to be changed
14
Class SalariedEmployee
15
Parent and Child Classes
16
Derived Class Types
• An hourly employee is an employee
– In C++, an object of type HourlyEmployee can be
used where an object of type Employee can be
used
– An object of a class type can be used wherever
any of its ancestors can be used
– An ancestor cannot be used wherever one of its
descendents can be used
17
Derived Class
Constructors
• A base class constructor is not inherited in a
derived class
– The base class constructor can be invoked by the
constructor of the derived class
– The constructor of a derived class begins by invoking
the constructor of the base class in the initialization
section:
HourlyEmployee::HourlyEmployee : Employee( ),
wage_rate( 0),
hours( )
{ //no code needed } Any Employee constructor
could be invoked
18
Default
Initialization
• If a derived class constructor does not invoke
a
base class constructor explicity, the base class
default constructor will be used
• If class B is derived from class A and class C
is derived from class B
– When a object of class C is created
• The base class A's constructor is the first invoked
• Class B's constructor is invoked next
• C's constructor completes execution
19
Private is Private
• A member variable (or function) that is private
in the parent class is not accessible to the
child class
– The parent class member functions must be used
to
access the private members of the parent
– This code would be illegal:
void HourlyEmployee::print_check( )
{
net_pay = hours * wage_rage;
• net_pay is a private member of Employee!
20
The protected Qualifier
21
Programming Style
• Using protected members of a class is a
convenience to facilitate writing the code of
derived classes.
• Protected members are not necessary
– Derived classes can use the public methods of
their
ancestor classes to access private members
• Many programming authorities consider it
bad style to use protected member variables
22
Redefinition of
Member Functions
• When defining a derived class, only list the
the inherited functions that you wish to
change
for the derived class
– The function is declared in the class definition
– HourlyEmployee and SalariedEmployee each have
their own definitions of print_check
23
Display Back Next
24
Display (1/2) Back Next
25
Display
(2/2) Back Next
26
Display Back Next
27
Display Back Next
28
Display (1/2) Back Next
29
Display
(2/2) Back Next
30
Display
Back Next
(1/2)
31
Display
(2/2) Back Next
32
Display
(1/2) Back Next
33
Display
(2/2) Back Next
34
Redefining or
Overloading
• A function redefined in a derived class has the
same number and type of parameters
– The derived class has only one function with the same
name as the base class
• An overloaded function has a different number
and/or type of parameters than the base class
– The derived class has two functions with the same
name as the base class
• One is defined in the base class, one in the derived class
35
Function Signatures
• A function signature is the function's name
with the sequence of types in the parameter
list, not including any const or '&'
– An overloaded function has multiple signatures
• Some compilers allow overloading based on
including const or not including const
36
Access to a
Redefined Base Function
• When a base class function is redefined in a
derived class, the base class function can still
be used
– To specify that you want to use the base class
version
of the redefined function:
HourlyEmployee sally_h;
sally_h.Employee::print_check( );
37
16.2
Inheritance Details
38
Copy Constructors and
Derived Classes
• If a copy constructor is not defined in a
derived
class, C++ will generate a default copy
constructor
– This copy constructor copies only the contents of
member variables and will not work with pointers
and dynamic variables
– The base class copy constructor will not be used
39
Operator = and
Derived Classes
• If a base class has a defined assignment
operator = and the derived class does not:
– C++ will use a default operator that will have
nothing to do with the base class assignment
operator
40
Destructors and
Derived Classes
• A destructor is not inherited by a derived class
• The derived class should define its own
destructor
41
The Assignment Operator
42
The Operator =
• This code segment shows how to begin the
implementation of the = operator for a
derived class:
Derived& Derived::operator= (const Derived& rhs)
{
Base::operator=(rhs)
– This line handles the assignment of the inherited member
variables by calling the base class assignment operator
– The remaining code would assign the member variables
introduced in the derived class
43
The Copy Constructor
• Implementation of the derived class copy
constructor is much like that of the assignment
operator:
Derived::Derived(const Derived& object)
:Base(object), <other initializing>
{…}
– Invoking the base class copy constructor sets up the
inherited member variables
• Since object is of type Derived it is also of type Base
44
Destructors in Derived
Classes
• If the base class has a working destructor,
defining the destructor for the defined class is
relatively easy
– When the destructor for a derived class is called, the
destructor for the base class is automatically called
– The derived class destructor need only use delete on
dynamic variables added in the derived class, and
data they may point to
45
Destruction
Sequence
• If class B is derived from class A and class C
is derived from class B…
– When the destructor of an object of class C goes
out of scope
• The destructor of class C is called
• Then the destructor of class B
• Then the destructor of class A
– Notice that destructors are called in the reverse
order of constructor calls
46
16.3
Polymorphism
47
A Late Binding Example
48
A Problem
• Suppose that class Figure has a function center
– Function center moves a figure to the center of the
screen by erasing the figure and redrawing it in the
center of the screen
– Function center is inherited by each of the derived
classes
• Function center uses each derived object's draw function to
draw the figure
• The Figure class does not know about its derived classes, so
it cannot know how to draw each figure
49
Virtual Functions
• Because the Figure class includes a method to
draw figures, but the Figure class cannot know
how to draw the figures, virtual functions are
used
• Making a function virtual tells the compiler that
you don't know how the function is implemented
and to wait until the function is used in a
program, then get the implementation from the
object.
– This is called late binding
50
Virtual Functions in C++
51
The Sale Class
• All sales will be derived from the base class
Sale
• The bill function of the Sale class is virtual
• The member function savings and operator <
each use bill
52
Virtual Function bill
• Because function bill is virtual in class Sale,
function savings and operator <, defined only in
the base class, can in turn use a version of bill
found in a derived class
– When a DiscountSale object calls its savings function,
defined only in the base class, function savings calls
function bill
– Because bill is a virtual function in class Sale, C++
uses the version of bill defined in the object that
called savings
53
DiscountSale::bill
• Class DiscountSale has its own version of
virtual function bill
– Even though class Sale is already compiled,
Sale::savings( ) and Sale::operator< can still use
function bill from the DiscountSale class
– The keyword virtual tells C++ to wait until bill is
used in a program to get the implementation of
bill
from the calling object
– DiscountSale is defined and used in Display 16.10
Display 16.11
54
Virtual Details
• To define a function differently in a derived class
and to make it virtual
– Add keyword virtual to the function declaration in
the base class
– virtual is not needed for the function declaration in
the derived class, but is often included
– virtual is not added to the function definition
– Virtual functions require considerable overhead so
excessive use reduces program efficiency
55
Overriding
56
Type Checking
• C++ carefully checks for type mismatches in
the use of values and variables
• This is referred to as strong type checking
– Generally the type of a value assigned to a
variable
must match the type of the variable
• Recall that some automatic type casting occurs
• Strong type checking interferes with the
concepts of inheritance
57
Type Checking and
Inheritance
• Consider
class Pet
{
public:
virtual void print();
string name;
}
and
class Dog :public Pet
{
public:
virtual void print();
string breed;
}
58
The Slicing Problem
• C++ allows the following assignments:
vdog.name = "Tiny";
vdog.breed = "Great Dane";
vpet = vdog;
• However, vpet will loose the breed member of
vdog since an object of class Pet has no breed
member
– This code would be illegal: cout << vpet.breed;
60
Extended Type Compatibility
61
Dynamic Variables
and Derived Classes
• Example:
Pet *ppet; void Dog::print( )
Dog *pdog; {
pdog = new Dog; cout << "name: "
pdog->name = "Tiny"; << name << endl;
pdog->breed = "Great cout << "breed: "
Dane"; << breed << endl;
ppet = pdog; }
62
Use Virtual Functions
• The previous example:
ppet->print( );
worked because print was declared as a virtual
function
• This code would still produce an error:
63
Why?
• ppet->breed is still illegal because ppet is a
pointer to a Pet object that has no breed member
• Function print( ) was declared virtual by class
Pet
– When the computer sees ppet->print( ), it checks
the virtual table for classes Pet and Dog and finds
that ppet points to an object of type Dog
• Because ppet points to a Dog object, code for Dog::print( )
is used
64
Remember Two
Rules
• To help make sense of object oriented
programming with dynamic variables,
remember these rules
1. If the domain type of the pointer p_ancestor is a base
class for the for the domain type of pointer
p_descendant,
the following assignment of pointers is allowed
p_ancestor = p_descendant;
and no data members will be lost
66
Virtual Destructors
• Destructors should be made virtual
– Consider Base *pBase = new Derived;
…
delete pBase;
– If the destructor in Base is virtual, the destructor
for
Derived is invoked as pBase points to a Derived
object, returning Derived members to the
freestore
• The Derived destructor in turn calls the Base destructor
67
Non-Virtual Destructors
• If the Base destructor is not virtual, only the
Base
destructor is invoked
68
Code
69
Display Back Next
70
Display Back Next
71
Display Back Next
72
Display Back Next
73
Display
Back Next
(1/2)
74
Display
Back Next
(2/2)
75
Templates
Slide 77
14.1
Templates for Algorithm
Abstraction
• Function definitions often use application
specific adaptations of more general
algorithms
– For example: The general algorithm used in
swap_values could swap variables of any type:
void swap_values(type_of_var& v1,
type_of_var& v2)
{
type_of_var temp;
temp = v1;
v1 = v2;
v2 = temp;
}
Slide 78
swap_values for char
• Here is a version of swap_values to swap
character variables:
– void swap_values(char& v1, char& v2)
{
char temp;
temp = v1;
v1 = v2;
v2 = temp;
}
Slide 79
A General swap_values
• A generalized version of swap_values is shown
here.
– void swap_values(type_of_var& v1, type_of_var& v2)
{
type_of_var temp;
temp = v1;
v1 = v2;
v2 = temp;
}
– This function, if type_of_var could accept any type,
could be used to swap values of any type
Slide 80
Templates for Functions
• A C++ function template will allow swap_values
to swap values of two variables of the same type
– Example: Type parameter
Template prefix template<class T>
void swap_values(T& v1, T& v2)
{
T temp;
temp = v1;
v1 = v2;
v = temp;
}
Slide 81
Template Details
• template<class T> is the template prefix
– Tells compiler that the declaration or definition that
follows is a template
– Tells compiler that T is a type parameter
• class means type in this context
(typename could replace class but class is usually used)
• T can be replaced by any type argument
(whether the type is a class or not)
• A template overloads the function name by
replacing T with the type used in a function call
Slide 82
Calling a Template
Function
• Calling a function defined with a template is
identical to calling a normal function
– Example:
To call the template version of swap_values
char s1, s2;
int i1, i2;
…
swap_values(s1, s2);
swap_values(i1, i2);
• The compiler checks the argument types and generates
an appropriate version of swap_values
Slide 83
Templates and
Declarations
• A function template may also have a separate
declaration
– The template prefix and type parameter are used
– Depending on your compiler
• You may, or may not, be able to separate declaration and
definitions of template functions just as you do with
regular functions
– To be safe, place template function definitions in the
same file where they are used…with no declaration
• A file included with #include is, in most cases, equivalent
to being "in the same file"
Slide 84
The Type Parameter T
Slide 86
Algorithm Abstraction
• Using a template function we can express
more
general algorithms in C++
• Algorithm abstraction means expressing
algorithms in a very general way so we can
ignore incidental detail
– This allows us to concentrate on the substantive
part of the algorithm
Slide 87
Program Example:
A Generic Sorting Function
• The sort function below uses an algorithm
that
does not depend on the base type of the array
void sort(int a[], int number_used)
{
int index_of_next_smallest;
for (int index = 0; index < number_used -1; index++)
{
index_of_next_smallest =
index_of_smallest(a, index, number_used);
swap_values(a[index], a[index_of_next_smallest]);
}
}
– The same algorithm could be used to sort an array of any
type
Slide 88
Generic Sorting:
Helping Functions
• sort uses two helper functions
– index_of_smallest also uses a general algorithm
and
could be defined with a template
– swap_values has already been adapted as a
template
Slide 89
Templates and Operators
Slide 90
Defining Templates
• When defining a template it is a good idea…
– To start with an ordinary function that accomplishes
the task with one type
• It is often easier to deal with a concrete case rather than
the general case
– Then debug the ordinary function
– Next convert the function to a template by replacing
type names with a type parameter
Slide 91
Inappropriate Types
for Templates
• Templates can be used for any type for which
the code in the function makes sense
– swap_values swaps individual objects of a type
– This code would not work, because the
assignment
operator used in swap_values does not work with
arrays:
int a[10], b[10];
<code to fill the arrays>
swap_values(a, b);
Slide 92
14.2
Templates for Data
Abstraction
• Class definitions can also be made more
general
with templates
– The syntax for class templates is basically the
same
as for function templates
• template<class T> comes before the template
definition
• Type parameter T is used in the class definition just like
any other type
• Type parameter T can represent any type
Slide 93
A Class Template
• The following is a class template
– An object of this class contains a pair of values of
type T
– template <class T>
class Pair
{
public:
Pair( );
Pair( T first_value, T second_value);
…
continued on next slide
Slide 94
Template Class Pair (cont.)
private:
T first;
T second;
};
Slide 95
Declaring
Template Class Objects
• Once the class template is defined, objects
may
be declared
– Declarations must indicate what type is to be used
for T
– Example: To declare an object so it can hold a pair
of integers:
Pair<int> score;
or for a pair of characters:
Pair<char> seats;
Slide 96
Using the Objects
• After declaration, objects based on a template
class are used just like any other objects
– Continuing the previous example:
score.set_element(1,3);
score.set_element(2,0);
seats.set_element(1, 'A');
Slide 97
Defining the Member
Functions
• Member functions of a template class are
defined the same way as member functions of
ordinary classes
– The only difference is that the member function
definitions are themselves templates
Slide 98
Defining a Pair
Constructor
• This is a definition of the constructor for class
Pair that takes two arguments
template<class T>
Pair<T>::Pair(T first_value, T second_value)
: first(first_value), second(second_value)
{
//No body needed due to initialization above
}
– The class name includes <T>
Slide 99
Defining set_element
• Here is a definition for set_element in the
template class Pair
void Pair<T>::set_element(int position, T value)
{
if (position = = 1)
first = value;
else if (position = = 2)
second = value;
else
…
}
Slide 100
Template Class Names
as Parameters
• The name of a template class may be used as
the
type of a function parameter
– Example: To create a parameter of type
Pair<int>:
Slide 101
Template Functions with
Template Class Parameters
• Function add_up from a previous example can
be made more general as a template function:
template<class T>
T add_up(const Pair<T>& the_pair)
//Precondition: operator + is defined for T
//Returns sum of the two values in the_pair
Slide 102
Program Example:
An Array Class
• The example in the following displays is a
class template whose objects are lists
– The lists can be lists of any type
Display 14.4 (1-2)
• The interface is found in
Display 14.5
The program is in
Display 14.6 (1-3)
The implementation is in
Slide 103
typedef and Templates
• You specialize a class template by giving a type
argument to the class name such as Pair<int>
– The specialized name, Pair<int>, is used just
like any class name
• You can define a new class type name with the
same meaning as the specialized name:
typedef Class_Name<Type_Arg> New_Type_Name;
Slide 104
Chapter 14 -- End
Slide 105
Display Back Next
Slide 106
Display Back Next
Slide 107
Display Back Next
Slide 108
Display Back Next
Slide 109
Display Back Next
Slide 110
Display Back Next
Slide 111
Display Back Next
Slide 112
Display Back Next
Slide 113
Display Back Next
Slide 114
Display Back Next
Slide 115