Title: Joaquin Vila
1ACS 168Problem Solving Using the Computer
Chapter 6 Classes
- By
- Joaquin Vila
- Prepared
- bv
- Sally Scott
2Chapter 6Defining Classes and Abstract Data Types
- Structures
- Structures for Diverse Data
- Structures as Function Arguments
- Initializing Structures
- Classes
- Defining Classes and Member Functions
- Public and Private Members
- Summary of Properties of Classes
- Constructors for Initialization
- Abstract Data Types
- Classes to Produce ADTs
3Some terms
- Object
- a special variable with its own special functions
as well as data - example cin is an object of the istream class
- Class
- a data type whose variables are objects
- Abstract data type
- a programmer defined data type, such as a class,
that meets certain standards.
4 6.1 Structures
- A language feature for grouping of related data
- Provides a way to represent a collection of
related data using a single unit. - A record with fields
- A structure definition defines a type
- struct CDAccount structure
tag -
- double balance Member names
- double interest_rate
- int term // months until maturity
-
- DONT FORGET THE SEMICOLON
5- Declaring structure variables
- CDAccount emp1 // declaration of Account
//structure variable emp1 - Declaration with initialization
- CDAccount emp2 2550.00, .07, 24
- Assignment statements for member variables
- emp1.balance 3000.00
- emp1.interest_rate .10
- emp1.term 36
- emp2 emp1 // assigns emp2 values of emp1
- emp1.balance emp2.balance // assigns balance
value
6- Specify member variables with the dot operator
- structure_name.member_variable_name
- emp1.balance
- Use member variables like any other variables
- Different structures may have same member
variable names - example
- CDAccount //structure for account with
balance, interest_rate, and term member
variables - SavingAccount // structure for savings
account with balance, interest_rate, and term
member variables
7Example of program using a StudentRecord
structure include ltiostreamgt using
namespace std struct StudentRecord int
student_number char grade
int main( ) StudentRecord
your_record your_record.student_number
2001 your_record.grade A cout ltlt
The grade for student ltlt
your_record.student_number ltlt is
ltlt your_record.grade ltlt endl
8Practice
Given the structure and structure variable
declaration Struct CDAccount double
balance double interest_rate int term
char initial1 char initial2 CDAccount
account
- What is the type of each of the following?
- account.balance
- account.interest_rate
- CDAccount.term
- saving_account.initial1
- account.intital2
- account
9Practice
Lect. Notes, pgs. 98-99
- Define a structure type named PartRecord with the
following fields - an integer partNumber
- a double price
- an integer numOnHand
- an integer numOrdered
- Declare two variables, partA and PartB of type
PartRecord - Declare a PartRecord named partC, initializing it
to be part number 151, with price 9.30, 10 on
hand, and 0 ordered.
10- Write a function that gets information about a
part from the user then returns a PartRecord.
The function should have no parameters.
11Structures as Function Arguments
- A function can have
- call-by-value parameters of structure type
and/or - call-by-reference parameters of structure type
and/or - return type that is a structure type
- Example
- CDAccount shrink_wrap(double the_balance,
double the_rate, int the_term) -
- CDAccount temp
- temp.balance the_balance
- temp.interest_rate the_rate
- temp.term the_term
- return temp
-
11
12More on Initializing Structures
- A structure may be initialized at the time it is
declared. - struct Date
-
- int month
- int day
- int year
-
- Date due_date 12, 31, 2001
- The sequence of values is used to initialize the
successive variables in the struct. The order is
essential. - It is an error to have more initializers than
variables. - If there are fewer initializers than variables,
the initializers provided are used to initialize
the data members. The remainder are initialized
to 0 for primitive types.
13Use of Hierarchical Structures
- If a structure has a subset of its members that
may be considered an entity, consider nested
structures. - Example A PersonInfo struct might
include a birthday structure - struct Date
-
- int month
- int day
- int year
-
- struct PersonInfo
-
- double height // inches
- int weight // pounds
- Date birthday // Date structure
-
14Use Hierarchical Structures, cont.
- Declare a variable of PersonInfo type as usual
- PersonInfo person1
- person1.birthday // This is a Date
structure, with members accessible
- // as
in any other structure variable. - If the structure variable person1 has been set,
the year a person was born can be output as
follows - cout ltlt person1.birthday.year
- structure person1 structure
birthday structure - variable member member
156.2 Classes Defining Classes and Member Functions
- A class is also a user defined data type
- Class variables are called objects
- An object is a variable that
- Has member variables (data members) and can hold
multiple values (like a structure) - Also has member functions (methods)
- A class definition specifies the data members
(much like a structure definition) and the
function members
variables
functions
class
15
16A class is a blueprint from which objects are
created
17Defining a Class
-
- class DayOfYear
-
- public
- void output( ) member
function prototype - int month data members
- int day
-
- The scope of a class starts at the name of the
class in the class definition and runs to the
closing curly brace and semicolon. - Member functions are declared inside of the class
definition, but are usually defined outside of it
(unless very short)
18- // Display 6.3 Class with a Member Function (1 of
2) - // Program to demonstrate a very simple example
of a class. - // A better version of the class DayOfYear will
be given in Display 6.4. - include ltiostreamgt
- using namespace std
- class DayOfYear
-
- public
- void output( )
member function prototype - int month
- int day
-
- int main( )
-
- DayOfYear today, birthday //
declaration of two objects of DayOfYear class - cout ltlt "Enter today's date\n"
18
19- // Display 6.3 Class with a Member Function (1 of
2) - cout ltlt "Today's date is "
- today. output( )
calls to the member
function output - cout ltlt "Your birthday is "
- birthday.output( )
-
the calling
object - if (today.month birthday.month
today.day birthday.day) - cout ltlt "Happy Birthday!\n"
- else
- cout ltlt "Happy Unbirthday!\n"
- return 0
- scope resolution operator
- //Uses iostream
- void DayOfYear output( )
member function definition -
- cout ltlt "month " ltlt month
- ltlt ", day " ltlt day ltlt endl
19
20Classes
- Objects of class type are declared much the same
as structure variables - Class member variables are also specified using
the dot operator - Programmer defined member functions of a class
are called exactly like structure member
variables, using the dot operator. - birthday.month birthday.output()
- class dot variable
class dot
member - name operator name
name operator function
21Defining Member Functions, cont.
- C provides the scope resolution operator
to define a member function outside of the class
definition - similar to dot operator that is used with object
members - used with a class name
- When defined outside, the function heading must
include the class name with the scope resolution
operator. The class name is called the type
qualifier - return_type Class_name Function_name(Parameter_
list) - void DayOfYear output( )
-
- // body of function member function
definition -
22Defining Member Functions, cont.
- Anything in the block of the function definition
is also considered to be in the scope of the
class. You can use names of any members of that
class (both data members and function members) in
the definition of a member function without the
dot operator. - When a member function is called, as in
- today.output( )
- the object today is called the calling
object.
void DayOfYearoutput( ) cout ltlt
month ltlt month ltlt , day ltlt day
ltlt endl
23Encapsulation and Information Hiding
- Combining several items such as variables, or
variables and functions, into a single package,
such as an object of some class, is called
encapsulation - Each object knows how to perform its own
functions and how to interact (interface) with
other objects. - Information hiding the black box concept
- The goal is to allow the user to know how to use
the functions, but does not know how the function
is implemented
24Access Control with Access Specifiers
- use in class definition to label the member
variables and functions - public members public
- can be accessed from any function, including
main( ) - private members private
- these members can only be accessed inside the
class own member functions, not by outside
functions. - this is default
- best to make all member variables private
- order and number of access specifiers in class
definition does not matter
25- Display 6.4 Class with Private Members (1 of 3)
- //Program to demonstrate the class DayOfYear.
- include ltiostreamgt
- using namespace std
- class DayOfYear
-
- public
- void input( )
- void output( )
- void set(int new_month, int new_day)
- //Precondition new_month and new_day form a
possible date. - //Postcondition The date is reset according
to the arguments. - int get_month( )
- //Returns the month, 1 for January, 2 for
February, etc.
A better class definition
25
26- Display 6.4 Class with Private Members (2 of 3)
- int main( )
-
- DayOfYear today, bach_birthday
- cout ltlt "Enter today's date\n"
- today.input( )
- cout ltlt "Today's date is "
- today.output( )
- bach_birthday.set(3, 21)
- cout ltlt "J. S. Bach's birthday is "
- bach_birthday.output( )
- if ( today.get_month( ) bach_birthday.get_m
onth( ) - today.get_day( )
bach_birthday.get_day( ) ) - cout ltlt "Happy Birthday Johann
Sebastian!\n" - else
26
27- Display 6.4 Class with Private Members (3 of 3)
- //Uses iostream
- void DayOfYearinput( )
-
- cout ltlt "Enter the month as a number "
- cin gtgt month
- cout ltlt "Enter the day of the month "
- cin gtgt day
-
- void DayOfYearoutput( )
-
- cout ltlt "month " ltlt month
- ltlt ", day " ltlt day ltlt endl
-
- void DayOfYearset(int new_month, int new_day)
-
- month new_month
- day new_day
-
27
28Why Public and Private Members?
- With an ideal class definition, the class author
should be able to change the details of the class
implementation without necessitating changes in
any program using the class . - Use accessor functions to access the data members
that are private and cannot be accessed directly.
29Public and Private Members
- There can be several public and private sections
in a class. - Members defined after public are accessible by
all functions. - Members defined after private are accessible
only by all functions defined in the class.
30- Display 6.5 The Bank Account Class (1 of 3)
- //Program to demonstrate the class BankAccount.
- include ltiostreamgt
- using namespace std
- //Class for a bank account
- class BankAccount
-
- public
- void set(int dollars, int cents, double
rate) - //Postcondition The account balance has been
set to dollars.cents - //The interest rate has been set to rate
percent. - void set(int dollars, double rate)
- //Postcondition The account balance has been
set to dollars.00. - //The interest rate has been set to rate
percent. - void update( )
- //Postcondition One year of simple interest
has been - //added to the account balance.
- double get_balance( )
30
31- Display 6.5 The Bank Account Class (2 of 3)
- // class BankAccount
- private
- double balance
- double interest_rate
- double fraction(double percent)
- //Converts a percent to a fraction. For
example, fraction(50.3) returns 0.503. -
- int main( )
-
- BankAccount account1, account2
- cout ltlt "Start of Test\n"
- account1.set(123, 99, 3.0)
- cout ltlt "account1 initial statement\n"
- account1.output(cout)
- account1.set(100, 5.0)
31
32- Display 6.5 The Bank Account Class (3 of 3)
- void BankAccountset(int dollars, int cents,
double rate) - balance dollars 0.01cents
- interest_rate rate
-
- void BankAccountset(int dollars, double rate)
- balance dollars
- interest_rate rate
-
- void BankAccountupdate( )
- balance balance fraction(interest_rate)ba
lance -
- double BankAccountfraction(double percent)
- return (percent/100.0)
-
- double BankAccountget_balance( )
- return balance
-
32
33Programming Tips
- Make Data Members private
- make all member variables private. This means
these variables can only be accessed or changed
using member functions. - Define Accessor Functions.
- consider providing a complete set of accessors to
data in useful formats. - Use the Assignment Operator with Objects The
assignment operator applies to struct and
class objects. You can use it to copy the same
values from one object to another.
34- Summary of Properties of Classes
- 1. Classes have both member variables and member
functions. - 2. A member (either variable or function) may be
public or private. - 3. Normally, all variable members of a class are
private. - 4. A private member of a class cannot be used
except in the definition of a function member of
the same class. - 5. The name of a member function for a class may
be overloaded just as the name of an ordinary
function. - 6. A class may use another class as the type for
a member variable. - 7. A function may have formal parameters with
class type. - 8. A function may return an object that is, a
class may be the type for the value returned by a
function. - (This works correctly with all the classes we
have seen so far. Under circumstances we will
encounter later, there are special members of
the class that must be defined for this to work
correctly. )
34
35Constructors for Initialization
C provides a special kind of member function
known as a constructor for automatic
initialization of class objects at definition.
- constructor is what builds the object.
- You can write your own constructors or C will
provide a default constructor for you. - A class constructor has the same name as the
class. - A constructor does not return a value, not even
void. (This is the only type of function that
does not have a return value.)
36Constructors for Initialization
- Each constructor should provide a value for every
member variable. - If the programmer does not write an explicit
constructor, a default constructor is
automatically provided. However, if any
constructor is coded, this automatic default
constructor is not provided. - Constructors can be written to allow input of
values for some or all variables. - Class constructors may be overloaded as needed.
- A default constructor should ALWAYS be included
in every class definition. If you write any
constructor at all, you should also write a
default constructor
37Constructors for Initialization
- class BankAccount
-
- public
- // Constructors
- BankAccount() // default constructor
- BankAccount( int dollars, int cents, double
rate) - . . .
- Private
- double balance
- double interest_rate
-
- BankAccountBankAccount(int dollars, int cents,
double rate) -
- balance dollars .01 cents
- interest_rate rate
38- Display 6.6 Class with Constructors (1 of 4)
- //Program to demonstrate the class BankAccount.
- include ltiostreamgt
- using namespace std
- //Class for a bank account
- class BankAccount
-
- public
- // Constructors
- BankAccount()
- //Initializes the account balance to 0.00
and the interest rate to 0.0. - BankAccount(int dollars, int cents, double
rate) - //Initializes the account balance to
dollars.cents and - //initializes the interest rate to rate
percent. - BankAccount(int dollars, double rate)
- //Initializes the account balance to
dollars.00 and - //initializes the interest rate to rate
percent. - // Accessor functions
38
39- Display 6.6 Class with Constructors (2 of 4)
- // other member functions
- void update()
- //Postcondition One year of simple interest
has been added to the account balance. - void output(ostream outs)
- //Precondition If outs is a file output
stream, then outs has already been connected to a
file. - //Postcondition Account balance and interest
rate have been written to the - //stream outs.
- private
- double balance
- double interest_rate
- // private helper function
- double fraction(double percent)
- //Converts a percent to a decimal fraction.
For example, fraction(50.3) returns 0.503. -
- int main()
-
- BankAccount account1, // uses default
constructor - account2(100, 2.3) // uses third
constructor
39
40- Display 6.6 Class with Constructors (3 of 4)
- account1 BankAccount(999, 99, 5.5) //
calls second constructor to update account1 - cout ltlt "account1 reset to the following\n"
- account1.output(cout)
- return 0
-
- BankAccountBankAccount()
-
- balance 0
- interest_rate 0.0
-
- BankAccountBankAccount(int dollars, int cents,
double rate) -
- balance dollars 0.01cents
- interest_rate rate
-
- BankAccountBankAccount(int dollars, double
rate) -
- balance dollars
40
41- Display 6.6 Class with Constructors (4 of 4)
- void BankAccountupdate( )
-
- balance balance fraction(interest_rate)ba
lance -
- double BankAccountfraction(double percent)
-
- return (percent/100.0)
-
- double BankAccountget_balance( )
-
- return balance
-
- double BankAccountget_rate( )
-
- return interest_rate
-
- //Uses iostream
- void BankAccountoutput(ostream outs)
41
42- Calling a Constructor
- A constructor is called automatically when an
object is declared. If you are not using the
default constructor, you must give the arguments
for the constructor when you declare the object. - Syntax (for an object declaration when using a
declared constructor other than the default
constructor) - ClassName ObjectName(Arguments_for_Const
ructor) - Example BankAccount account1(100, 2.3)
- Calling a constructor can be called after object
declaration - Syntax (for an explicit constructor call)
- ObjectName
ConstructorName(Arguments_for_Constructor) - Example account1 BankAccount(200, 3.5)
- A constructor must have the same name as the
class of which it is a member. - Hence Class_Name and Constructor_Name are
the same identifier.
42
43Pitfall Constructors with no arguments
- The declaration
- BankAccount object_name(100, 2.3)
- invokes the BankAccount constructor that
requires two parameters. - The function call
- func()
- invokes a function func that takes no parameters
- Conversely,
- BankAccount objectname()
- does NOT invoke the no-parameter constructor.
- Rather, this line of code defines a function that
returns an object of BankAccount type.
43
44- Constructors with No Arguments
- When you declare an object and want the
constructor with zero arguments to be called, you
do not include parentheses. For example, to
declare an object and pass two arguments, you
might do this - BankAccount account(100, 2.3)
- However, to cause the constructor with NO
arguments, to be called, you declare the object - BankAccount account
- You do NOT declare the object
- BankAccount account()
44
456.3 Abstract Data Types
- A data type is called an Abstract Data Type (ADT)
if the programmers who use the type do not have
access to the details of how the values and
operations are implemented. - Programmer defined types are not automatically
ADTs. Care is required in construction of
programmer defined types to prevent unintuitive
and difficult-to-modify code.
45
46Classes to Produce ADTs How to make an ADT
- Member variables -
- make private.
- Basic operations that the programmer needs
- make a public member function of the class for
each one, and fully specify how to use each such
function (use clear comments). - Helping functions
- make private member functions.
- The interface
- the public member functions along with commentary
telling how to use the member functions. The
interface of an ADT should tell all the
programmer need to know to use the ADT. - The implementation
- private members of the class and the definitions
of all member functions. This is information the
programmer should NOT NEED to use the class.
46
47Remember
- The client programmer does not need to know how
data is stored, nor how the functions are
implemented. - Consequently alternative implementations may
store different value types.
47
48- Display 6.7 Alternative BankAccount
Implementation(1 of 6) - //Demonstrates an alternative implementation of
the class BankAccount. - include ltiostreamgt
- include ltcmathgt
- using namespace std Notice
that the public members of - //Class for a bank account BankAccount
look and behave - class BankAccount exactly
the same as in Display 6.6 -
- public
- BankAccount(int dollars, int cents, double
rate) - //Initializes the account balance to
dollars.cents and - //initializes the interest rate to rate
percent. - BankAccount(int dollars, double rate)
- //Initializes the account balance to
dollars.00 and - //initializes the interest rate to rate
percent. - BankAccount( )
- //Initializes the account balance to 0.00
and the interest rate to 0.0.
48
49- Display 6.7 Alternative BankAccount
Implementation(2 of 6) - double get_balance( )
- //Returns the current account balance.
- double get_rate( )
- //Returns the current account interest rate
as a percent. - void output(ostream outs)
- //Precondition If outs is a file output
stream, then - //outs has already been connected to a file.
- //Postcondition Account balance and interest
rate have been - //written to the stream outs.
- private
- int dollars_part
- int cents_part
- double interest_rate//expressed as a
fraction, e.g., 0.057 for 5.7 - double fraction(double percent)
New - //Converts a percent to a fraction. For
example, fraction(50.3) - //returns 0.503.
- double percent(double fraction_value)
- //Converts a fraction to a percent. For
example, percent(0.503)
49
50- Display 6.7 Alternative BankAccount
Implementation(3 of 6) - int main( )
-
- BankAccount account1(100, 2.3), account2
- cout ltlt "account1 initialized as follows\n"
The body of main is identical - account1.output(cout)
to that in Display 6.6, the - cout ltlt "account2 initialized as follows\n"
screen output is also identical - account2.output(cout)
Display 6.6. - account1 BankAccount(999, 99, 5.5)
- cout ltlt "account1 reset to the following\n"
- account1.output(cout)
- return 0
-
- BankAccountBankAccount(int dollars, int cents,
double rate) -
- dollars_part dollars
- cents_part cents
- interest_rate fraction(rate)
50
51- Display 6.7 Alternative BankAccount
Implementation(4 of 6) - BankAccountBankAccount(int dollars, double
rate) -
- dollars_part dollars
- cents_part 0
- interest_rate fraction(rate)
-
- BankAccountBankAccount( )
-
- dollars_part 0
- cents_part 0
- interest_rate 0.0
-
- double BankAccountfraction(double percent)
-
- return (percent/100.0)
51
52- Display 6.7 Alternative BankAccount
Implementation(5 of 6) - //Uses cmath
- void BankAccountupdate( )
-
- double balance get_balance( )
- balance balance interest_ratebalance
- dollars_part floor(balance)
- cents_part floor((balance -
dollars_part)100) -
- double BankAccountget_balance( )
-
- return (dollars_part 0.01cents_part)
-
- double BankAccountpercent(double
fraction_value) -
- return (fraction_value100)
-
- double BankAccountget_rate( )
-
52
53- Display 6.7 Alternative BankAccount
Implementation(6 of 6) - //Uses iostream
- void BankAccountoutput(ostream outs)
-
- outs.setf(iosfixed)
new definition - outs.setf(iosshowpoint)
- outs.precision(2)
- outs ltlt "Account balance " ltlt get_balance( )
ltlt endl - outs ltlt "Interest rate " ltlt get_rate( ) ltlt
"" ltlt endl -
- The new definitions of get_balance and get_rate
- ensure that the output will still be in the
correct units.
53
54- Information Hiding
- You should write the functions so that they can
be used with no knowledge of how they were
written as if they were black boxes. We know
only the interface and specification. - All the programmer needs to know about a function
is its prototype and accompanying comment that
explains how to use the function. - The use of private member variables and private
member functions in the definition of an abstract
data type is another way to implement information
hiding, where we now apply the principle to data
values as well as to functions.
54
55The Class Diagram (lec. notes, p.97)
BankAccount
Class name member variables member functions
(with parameters) function return type
public members _ private members
-balance double -interest_rate
double BankAccount (dollars, cents,
rate) BankAccount(dollars, rate) BankAccount(
) update( ) void get_balance( )
double get_rate( ) double output(outs)
void -fraction(percent) double