Absolute C++ (phần 7) potx - Pdf 17

240 Structures and Classes
to tell what a member function is a member of. However, the scope resolution operator ::
is used with a class name, whereas the dot operator is used with objects (that is, with class
variables). The scope resolution operator consists of two colons with no space between
them. The class name that precedes the scope resolution operator is often called a type
qualifier, because it specializes (“qualifies”) the function name to one particular type.
Look at the definition of the member function
DayOfYear::output given in Display
6.3. Notice that in the function definition of
DayOfYear::output, we used the member
names
month and day by themselves without first giving the object and dot operator. That
is not as strange as it may at first appear. At this point we are simply defining the member
function
output. This definition of output will apply to all objects of type DayOfYear, but
at this point we do not know the names of the objects of type
DayOfYear that we will use,
so we cannot give their names. When the member function is called, as in
today.output( );
all the member names in the function definition are specialized to the name of the call-
ing object. So, the above function call is equivalent to the following:
{
switch (today.month)
{
case 1:
.
.
.
}
cout << today.day;
}

E
XAMPLE
See Display 6.3. Note that the member variables (month and day) are not preceded by an object
name and dot when they occur in a member function definition.
06_CH06.fm Page 240 Wednesday, August 13, 2003 12:54 PM
Classes 241
Self-Test Exercises
In the function definition for a member function, you can use the names of all mem-
bers of that class (both the data members and the function members) without using the
dot operator.
9. Below we have redefined the class DayOfYear from Display 6.3 so that it now has one
additional member function called
input. Write an appropriate definition for the member
function
input.
class DayOfYear
{
public:
T
HE
D
OT
O
PERATOR

AND

THE
S
COPE

ULL
-F
LEDGED
T
YPE
A class is a type just like the types int and double. You can have variables of a class type, you
can have parameters of a class type, a function can return a value of a class type, and more gen-
erally, you can use a class type like any other type.
06_CH06.fm Page 241 Wednesday, August 13, 2003 12:54 PM
242 Structures and Classes
void input( );
void output( );
int month;
int day;

};
10. Given the following class definition, write an appropriate definition for the member func-
tion
set.
class Temperature
{
public:
void set(double newDegrees, char newScale);
//Sets the member variables to the values given as
//arguments.
double degrees;
char scale; //’F’ for Fahrenheit or ’C’ for Celsius.

};
11. Carefully distinguish between the meaning and use of the dot operator and the scope reso-

Classes 243
A programmer who uses a class also should not need to know how the data of the
class is implemented. The implementation of the data should be as hidden as the imple-
mentation of the member functions. In fact, it is close to impossible to distinguish
between hiding the implementation of the member functions and the implementation
of the data. To a programmer, the class
DayOfYear (Display 6.3) has dates as data, not
numbers. The programmer should not know or care whether the month March is
implemented as the
int value 3, the quoted string "March", or in some other way.
Defining a class so that the implementation of the member functions and the imple-
mentation of the data in objects are not known, or is at least irrelevant, to the program-
mer who uses the class is known by a number of different terms. The most common
terms used are information hiding, data abstraction, and encapsulation, each of
which means that the details of the implementation of a class are hidden from the pro-
grammer who uses the class. This principle is one of the main tenets of object-oriented
programming (OOP). When discussing OOP, the term that is used most frequently is
encapsulation. One of the ways to apply this principle of encapsulation to your class
definitions is to make all member variables private, which is what we discuss in the next
subsection.

PUBLIC AND PRIVATE MEMBERS
Look back at the definition of the type DayOfYear given in Display 6.3. In order to use
that class, you need to know that there are two member variables of type
int that are
named
month and day. This violates the principle of encapsulation (information hiding)
that we discussed in the previous subsection. Display 6.4 is a rewritten version of the
class
DayOfYear that better conforms to this encapsulation principle.

variable
06_CH06.fm Page 243 Wednesday, August 13, 2003 12:54 PM
244 Structures and Classes
Display 6.4 Class with Private Members
(part 1 of 3)
1 #include <iostream>
2 #include <cstdlib>
3 using namespace std;
4 class DayOfYear
5 {
6 public:
7 void input(
);
8 void output(
);
9 void set(int newMonth, int newDay);
10 //Precondition: newMonth and newDay form a possible date.
11 void set(int newMonth);
12 //Precondition: 1 <= newMonth <= 12
13 //Postcondition: The date is set to the first day of the given month.

14 int getMonthNumber(
); //Returns 1 for January, 2 for February, etc.
15 int getDay(
);
16 private:
17 int month;
18 int day;
19 };
20 int main(

DayOfYear that we gave
in Display 6.3.
Note that the function name set is
overloaded. You can overload a
member function just like you can
overload any other function.
06_CH06.fm Page 244 Wednesday, August 13, 2003 12:54 PM
Classes 245
Display 6.4 Class with Private Members
(part 2 of 3)
42 {
43 if ((newMonth >= 1) && (newMonth <= 12))
44 month = newMonth;
45 else
46 {
47 cout << "Illegal month value! Program aborted.\n";
48 exit(1);
49 }
50 if ((newDay >= 1) && (newDay <= 31))
51 day = newDay;
52 else
53 {
54 cout << "Illegal day value! Program aborted.\n";
55 exit(1);
56 }
57 }
58 //Uses iostream and cstdlib:
59 void DayOfYear::set(int newMonth)
60 {
61 if ((newMonth >= 1) && (newMonth <= 12))

be used in member
function definitions
(but not elsewhere).
06_CH06.fm Page 245 Wednesday, August 13, 2003 12:54 PM
246 Structures and Classes
the implementation of the data for the class DayOfYear. If you look carefully at the pro-
gram in Display 6.4, you will see that the only place the member variable names
month
and day are used is in the definitions of the member functions. There is no reference to
today.month, today.day, bachBirthday.month, or bachBirthday.day anyplace outside
the definitions of member functions.
All the items that follow the word
public: (in this case the member functions) are
said to be public, which means that they can be referenced by name anyplace. There
are no restrictions on the use of public members.
Any member variables can be either public or private. Any member functions can be
public or private. However, normal good programming practices require that all mem-
ber variables be private and that typically most member functions be public.
You can have any number of occurrences of
public and private access specifiers in
a class definition. Every time you insert the label
public:
the list of members changes from private to public. Every time you insert the label
private:
the list of members changes back to being private members. You need not have just one
public and one private group of members. However, it is common to have just one
public section and one private section.
Display 6.4 Class with Private Members
(part 3 of 3)
86 if ((month < 1) || (month > 12) || (day < 1) || (day > 31))

the public members first. This allows for easy viewing of the portions programmers
using the class actually get to use. You can make your own decision on what you wish
to place first, but the examples in the book will go along with the majority and list the
public members before the private members.
In one sense C++ seems to favor placing the private members first. If the first group
of members has neither the
public: nor the private: specifier, then members of that
group will automatically be private. You will see this default behavior used in code and
should be familiar with it. However, we will not use it in this book.

ACCESSOR AND MUTATOR FUNCTIONS
You should always make all member variables in a class private. You may sometimes
need to do something with the data in a class object, however. The member functions
will allow you to do many things with the data in an object, but sooner or later you will
want or need to do something with the data for which there is no member function.
How can you do anything new with the data in an object? The answer is that you can do
anything you might reasonably want, provided you equip your classes with suitable
accessor and mutator functions. These are member functions that allow you to access
and change the data in an object in a very general way. Accessor functions allow you to
read the data. In Display 6.4, the member functions
getMonthNumber and getDay are
accessor functions. The accessor functions need not literally return the values of each
member variable, but they must return something equivalent to those values. For exam-
ple, for a class like
DayOfYear, you might have an accessor function return the name of
the month as some sort of string value, rather than return the month as a number.
Mutator functions allow you to change the data. In Display 6.4, the two functions
named
set are mutator functions. It is traditional to use names that include the word
get for accessor functions and names that include the word set for mutator functions.

public:
void setPrice(double newPrice);
void setProfit(double newProfit);
double getPrice(
);
private:
double price;
double profit;
double getProfit(
);
};
and suppose the main function of your program contains the following declaration and that
the program somehow sets the values of all the member variables to some values:
Automobile hyundai, jaguar;
Which of the following statements are then allowed in the main function of your program?
hyundai.price = 4999.99;
jaguar.setPrice(30000.97);
double aPrice, aProfit;
aPrice = jaguar.getPrice(
);
aProfit = jaguar.getProfit(
);
aProfit = hyundai.getProfit(
);
hyundai = jaguar;
13. Suppose you change Self-Test Exercise 12 so that in the definition of the class Automobile
all member variables are public instead of private. How would this change your answer to
the question in Self-Test Exercise 12?
14. Explain what
public: and private: mean in a class definition.

cc
ee
ee
or AA
AA
PP
PP
II
II
. There is some disagreement on exactly what the initials API
stand for, but it is generally agreed that they stand for something like
application programmer
interface
API
06_CH06.fm Page 248 Wednesday, August 13, 2003 12:54 PM
Classes 249
Tip
interface
or
abstract programming interface
or something similar. In this book we will call these
rules the
interface
for the class. It is important to keep in mind a clear distinction between the
interface and the implementation of a class. If your class is well designed, then any programmer
who uses the class need only know the interface for the class and need not know any details of the
implementation of the class. A class whose interface and implementation are separated in this
way is sometimes called an
abstract data type (ADT)
or a nicely encapsulated class. In Chapter 11

pp
pp
ll
ll
ee
ee
mm
mm
ee
ee
nn
nn
tt
tt
aa
aa
tt
tt
ii
ii
oo
oo
nn
nn
of a class tells how the class interface is realized as C++ code. The implemen-
tation consists of the private members of the class and the definitions of both the public and pri-
vate member functions. Although you need the implementation in order to run a program that
uses the class, you should not need to know anything about the implementation in order to write
the rest of a program that uses the class; that is, you should not need to know anything about the
implementation in order to write the

250 Structures and Classes
public:
void input(
);
void output(
);
void set(int newMonth, int newDay);
//Precondition: newMonth and newDay form a possible date.
//Postcondition: The date is reset according to the arguments.
void set(int newMonth);
//Precondition: 1 <= newMonth <= 12
//Postcondition: The date is set to first day of the month.
int getMonthNumber(
);
//Returns 1 for January, 2 for February, etc.
int getDay(
);
private:
char firstLetter;//of month
char secondLetter;//of month
char thirdLetter;//of month
int day;
};
In this version, a month is represented by the first three letters in its name, such as ’J’, ’a’, and
’n’ for January. The member functions should also be rewritten, of course, but they can be
rewritten to behave
exactly
as they did before. For example, the definition of the function get-
MonthNumber
might start as follows:

Class_Name
{
.
public:
Member_SpecificationN+1
Member_SpecificationN+2
.
.
.
private:
Member_Specification_1
Member_Specification_2
.
.
.

Member_SpecificationN
};
Each
Member_Specification_i
is either a member variable declaration or a member function
declaration (prototype).
Additional public: and private: sections are permitted. If the first group of members does
not have either a
public: or a private: label, then it is the same as if there were a private:
before the first group.
E
XAMPLE
class Bicycle
{

private.
T
HINKING
O
BJECTS
If you have not programmed with classes before, it can take a little while to get the feel of pro-
gramming with them. When you program with classes, data rather than algorithms takes center
stage. It is not that there are no algorithms. However, the algorithms are made to fit the data, as
opposed to designing the data to fit the algorithms. It’s a difference in point of view. In the
extreme case, which is considered by many to be the best style, you have no global functions at
all, only classes with member functions. In this case, you define objects and how the objects inter-
act, rather than algorithms that operate on data. We will discuss the details of how you accom-
plish this throughout this book. Of course, you can ignore classes completely or relegate them to a
minor role, but then you are really programming in C, not C++.
16. When you define a C++ class, should you make the member variables public or private?
Should you make the member functions public or private?
17. When you define a C++ class, what items are considered part of the interface? What items
are considered part of the implementation?
■ A structure can be used to combine data of different types into a single (compound)
data value.
■ A class can be used to combine data and functions into a single (compound) object.
■ A member variable or a member function for a class can be either public or private.
If it is public, it can be used outside the class. If it is private, it can be used only in
the definition of a member function.
Chapter Summary
06_CH06.fm Page 252 Wednesday, August 13, 2003 12:54 PM
Answers to Self-Test Exercises 253
■ A function can have formal parameters of a class or structure type. A function can
return values of a class or structure type.
■ A member function for a class can be overloaded in the same way as ordinary func-

{
cout << "Enter shoe style (one letter): ";
cin >> newShoe.style;
cout << "Enter shoe price $";
cin >> newShoe.price;
}
06_CH06.fm Page 253 Wednesday, August 13, 2003 12:54 PM
254 Structures and Classes
8. ShoeType discount(ShoeType oldRecord)
{
ShoeType temp;
temp.style = oldRecord.style;
temp.price = 0.90*oldRecord.price;
return temp;
}
9. void DayOfYear::input( )
{
cout << "Enter month as a number: ";
cin >> month;
cout << "Enter the day of the month: ";
cin >> day;
}
10. void Temperature::set(double newDegrees, char newScale)
{
degrees = newDegrees;
scale = newScale;
}
11. Both the dot operator and the scope resolution operator are used with member names to
specify of what class or structure the member name is a member. If
class DayOfYear is as

private: section in a class.
16. The member variables should all be private. The member functions that are part of the
interface should be public. You may also have auxiliary (helping) functions that are only
used in the definitions of other member functions. These auxiliary functions should be
private.
17. All the declarations of private member variables are part of the implementation. (There
should be no public member variables.) All the declarations for public member functions
of the class (which are listed in the class definitions), as well as the explanatory comments
for these declarations, are parts of the interface. All the declarations for private member
functions are parts of the implementation. All member function definitions (whether the
function is public or private) are parts of the implementation.
PROGRAMMING PROJECTS
1. Write a grading program for a class with the following grading policies.
a. There are two quizzes, each graded on the basis of 10 points.
b. There is one midterm exam and one final exam, each graded on the basis of 100 points.
c. The final exam counts for 50% of the grade, the midterm counts for 25%, and the two
quizzes together count for a total of 25%. (Do not forget to normalize the quiz scores. They
should be converted to a percentage before they are averaged in.)
Any grade of 90 or more is an A, any grade of 80 or more (but less than 90) is a B, any
grade of 70 or more (but less than 80) is a C, any grade of 60 or more (but less than 70) is a
D, and any grade below 60 is an F. The program will read in the student’s scores and out-
put the student’s record, which consists of two quiz and two exam scores as well as the stu-
dent’s average numeric score for the entire course and final letter grade. Define and use a
structure for the student record.
2. Define a class for a type called
CounterType. An object of this type is used to count things,
so it records a count that is a nonnegative whole number. Include a mutator function that
sets the counter to a count given as an argument. Include member functions to increase the
count by one and to decrease the count by one. Be sure that no member function allows the
value of the counter to become negative. Also, include a member function that returns the

a. A display of the amount dispensed,
b. A display of the amount charged for the amount dispensed
d. A display of the cost per gallon, liter, or other unit of volume that is used where you reside.
e. Before use, the gas pump must reset the amount dispensed and amount charged to zero.
f. Actual behavior of the gas pump is, once started, it dispenses as long as you hold the nozzle
lever. Peculiarities of console I/O make it difficult to continue to dispense while waiting for
signal to stop. One solution is to model this behavior by having the user repeatedly press
the return (enter) key, dispensing a quantum of fuel and recomputing the amount charged,
say 0.1 gallons at each press.
g. A stop dispensing control of some kind is needed.
Implement the behavior of the gas pump as declarations of member functions of the gas
pump class, then write implementations of these member functions. You will have to
decide if there is data the gas pump has to keep track of that the user of the pump should
not have access to. If so, make these private member variables.
06_CH06.fm Page 256 Wednesday, August 13, 2003 12:54 PM
2.5
For additional online
Programming
Projects, click the
CodeMate icons
below.
1.7

7

Constructors and Other Tools
7.1 CONSTRUCTORS 258
Constructor Definitions 258
Pitfall: Constructors with No Arguments 263
Explicit Constructor Calls 265

7

Constructors and Other Tools

Give us the tools and, and we will finish the job.

Winston Churchill

, Radio broadcast (February 9, 1941)
INTRODUCTION

This chapter presents a number of important tools to use when programming
with classes. The most important of these tools are class constructors, a kind of
function used to initialize objects of the class.
Section 7.3 introduces

vectors

as an example of classes and as a preview of
the Standard Template Library (STL). Vectors are similar to arrays but can
grow and shrink in size. The STL is an extensive library of predefined classes.
Section 7.3 may be covered now or later. The material in Chapters 8 through
18 does not require the material in Section 7.3, so you may postpone covering
vectors (Section 7.3) if you wish.
Sections 7.1 and 7.2 do not use the material in Chapter 5 but do use the
material in Chapter 6. Section 7.3 requires Chapters 1 through 6 as well as
Section 7.1.

Constructors



1. A constructor must have the same name as the class. For example, if the class is named

BankAccount

, then any constructor for this class must be named

BankAccount

.
2. A constructor definition cannot return a value. Moreover, no type, not even

void

,
can be given at the start of the function declaration or in the function header.
For example, suppose we wanted to add a constructor for initializing the month and
day for objects of type

DayOfYear

, which we gave in Display 6.4 and redefine in what
follows so it includes a constructor. (We have omitted some of the comments to save
space, but they should be included in an actual program.)

class DayOfYear
{
public:
DayOfYear(int monthValue, int dayValue);
//Initializes the month and day to arguments.


, which is the name of the class.
Also notice that the declaration (prototype) for the constructor

DayOfYear

does not
start with

void

or any other type name. Finally, notice that the constructor is placed in
the public section of the class definition. Normally, you should make your constructors
public member functions. If you were to make all your constructors private members,
then you would not be able to declare any objects of that class type, which would make
the class completely useless.
With the redefined class

DayOfYear

, two objects of type

DayOfYear

can be declared
and initialized as follows:

DayOfYear date1(7, 4), date2(5, 5);

Assuming that the definition of the constructor performs the initializing action that we

sents the date May 5. What happens is that the object

date1

is declared, and then the
constructor

DayOfYear

is called with the two arguments

7

and

4

. Similarly,

date2

is
declared, and then the constructor

DayOfYear

is called with the arguments

5


date2

as
follows:

DayOfYear date1(7, 4), date2(5, 5);

The definition of a constructor is given in the same way as any other member func-
tion. For example, if you revise the definition of the class

DayOfYear

by adding the con-
structor just described, you need to also add a definition of the constructor, which
might be as follows:

DayOfYear::DayOfYear(int monthValue, int dayValue)
{
month = monthValue;
day = dayValue;
}

Since the class and the constructor function have the same name, the name

DayOfYear

occurs twice in the function heading; the

DayOfYear


oo
nn
nn
ss
ss
tt
tt
rr
rr
uu
uu
cc
cc
tt
tt
oo
oo
rr
rr
is a member function of a class that has the same name as the class. A constructor is
called automatically when an object of the class is declared. Constructors are used to initialize
objects. A constructor must have the same name as the class of which it is a member.

07_CH07.fm Page 260 Wednesday, August 13, 2003 12:58 PM
Constructors 261

DayOfYear::DayOfYear(int monthValue, int dayValue)
: month(monthValue), day(dayValue)
{/*Body intentionally empty*/}



DayOfYear::DayOfYear

, just as you can
overload any other member function name. In fact, constructors usually are overloaded
so that objects can be initialized in more than one way. For example, in Display 7.1 we
have redefined the class

DayOfYear

so that it has three versions of its constructor. This
redefinition overloads the constructor name

DayOfYear

so that it can have two argu-
ments (as we just discussed), one argument, or no arguments.
Notice that in Display 7.1, two constructors call the member function

testDate to
check that their initialized values are appropriate. The member function
testDate is
private since it is only intended to be used by other member functions and so is part of
the hidden implementation details.
We have omitted the member function
set from this revised class definition of
DayOfYear. Once you have a good set of constructor definitions, there is no need for
any other member functions to set the member variables of the class. You can use the
constructor
DayOfYear in Display 7.1 for the same purposes that you would use the

18 private:
19 int month;
20 int day;
21 void testDate( );
22 };
23 int main(
)
24 {
25 DayOfYear date1(2, 21), date2(5), date3;
26 cout << "Initialized dates:\n";
27 date1.output( ); cout << endl;
28 date2.output( ); cout << endl;
29 date3.output( ); cout << endl;
30 date1 = DayOfYear(10, 31);
31 cout << "date1 reset to the following:\n";
32 date1.output( ); cout << endl;
33 return 0;
34 }
35
36 DayOfYear::DayOfYear(int monthValue, int dayValue)
37 : month(monthValue), day(dayValue)
38 {
39 testDate( );
40 }
This definition of DayOfYear is an improved version
of the class
DayOfYear given in Display 6.4.
default constructor
This causes a call to the default
constructor. Notice that there are

49 {
50 if ((month < 1) || (month > 12))
51 {
52 cout << "Illegal month value!\n";
53 exit(1);
54 }
55 if ((day < 1) || (day > 31))
56 {
57 cout << "Illegal day value!\n";
58 exit(1);
59 }
60 }
S
AMPLE
D
IALOGUE
Initialized dates:
February 21
May 1
January 1
date1 reset to the following:
October 31
<
Definitions of the other member
functions are the same as in Display 6.4.
>
07_CH07.fm Page 263 Wednesday, August 13, 2003 12:58 PM
264 Constructors and Other Tools
The object date1 is initialized by the constructor that takes two arguments, the object date2 is
initialized by the constructor that takes one argument, and the object


AN
O
BJECT
D
ECLARATION
W
HEN
Y
OU
H
AVE
C
ONSTRUCTORS
Class_Name

Variable_Name(Arguments_for_Constructor);
E
XAMPLE
DayOfYear holiday(7, 4);
S
YNTAX

FOR

AN
E
XPLICIT
C
ONSTRUCTOR


Nhờ tải bản gốc
Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status