Tải bản đầy đủ (.pdf) (10 trang)

Absolute C++ (4th Edition) part 26 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (321.85 KB, 10 trang )

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-
tions are overloaded.
■ When defining a C++ class, you should separate the interface and implementation
so that any programmer who uses the class need only know the interface and need
not even look at the implementation. This is the principle of encapsulation.
ANSWERS TO SELF-TEST EXERCISES
1. a. double
b. double
c. illegal—cannot use a structure tag instead of a structure variable
d.
char
e. CDAccountV2
2. A $9.99
A $1.11
3. A semicolon is missing from the end of the definition of Stuff.
4.
A x = {1,2};
5. a. Too few initializers; not a syntax error. After initialization, month==12, day==21, and
year==0. Member variables not provided an initializer are initialized to a zero of the
appropriate type.
b. Correct after initialization.
12==month, 21==day, and 1995==year.
c. Error: too many initializers.
6.
struct EmployeeRecord
{
double wageRate;
int vacation;


char status;
};
7. void readShoeRecord(ShoeType& newShoe)
{
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
defined in Display 6.3 and
today is an object of the class DayOfYear, then the member
month may be accessed with the dot operator: today.month. When we give the definition
of a member function, the scope resolution operator is used to tell the compiler that this
function is the one declared in the class.
12.
hyundai.price = 4999.99; //ILLEGAL. price is private.
jaguar.setPrice(30000.97); //LEGAL
double aPrice, aProfit;//LEGAL
aPrice = jaguar.getPrice(
);//LEGAL
aProfit = jaguar.getProfit(
);//ILLEGAL. getProfit is
//private.
aProfit = hyundai.getProfit(
);//ILLEGAL. getProfit is
// private.
hyundai = jaguar;//LEGAL
13. After the change, they would all be legal.
14. All members (member variables and member functions) that are marked
private: can
only be accessed by name in the definitions of member functions (both public and private)
of the same class. Members marked
public: have no restrictions on where they can be
used.
06_CH06.fm Page 254 Wednesday, August 13, 2003 12:54 PM
Programming Projects 255

15. a. Only one. The compiler warns if you have no public: members in a class (or struct,
for that matter).
b. None, but we normally expect to find at least one
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
current count value and one that outputs the count. Embed your class definition in a test
program.
3. The type
Point is a fairly simple data type, but under another name (the template class
pair) this data type is defined and used in the C++ Standard Template Library, although
you need not know anything about the Standard template Library to do this exercise. Write
a definition of a class named
Point that might be used to store and manipulate the location
06_CH06.fm Page 255 Wednesday, August 13, 2003 12:54 PM
256 Structures and Classes
of a point in the plane. You will need to declare and implement the following member
functions:
a. a member function
set that sets the private data after an object of this class is created.
b. a member function to move the point by an amount along the vertical and horizontal
directions specified by the first and second arguments.
c. a member function to rotate the point by 90 degrees clockwise around the origin.
d. two
const inspector functions to retrieve the current coordinates of the point.
Document these functions with appropriate comments. Embed your class in a test program
that requests data for several points from the user, creates the points, then exercises the
member functions.
4. Write the definition for a class named
GasPump to be used to model a pump at an automo-
bile service station. Before you go further with this programming exercise, write down the
behavior you expect from a gas pump from the point of view of the purchaser.
Below are listed things a gas pump might be expected to do. If your list differs, and you

think your list is as good or better than these, then consult your instructor. You and your
instructor should jointly decide what behavior you are to implement. Then implement and
test the agreed upon design for a gas pump class.
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
Tip: Always Include a Default Constructor 265
Example:

BankAccount
Class 268
Class Type Member Variables 274
7.2 MORE TOOLS 277
The

const
Parameter Modifier 277
Pitfall: Inconsistent Use of

const
279
Inline Functions 284
Static Members 286
Nested and Local Class Definitions 289
7.3 VECTORS—A PREVIEW OF THE STANDARD
TEMPLATE LIBRARY 290
Vector Basics 290
Pitfall: Using Square Brackets beyond the Vector Size 293
Tip: Vector Assignment Is Well Behaved 294
Efficiency Issues 294
CHAPTER SUMMARY 296
ANSWERS TO SELF-TEST EXERCISES 296
PROGRAMMING PROJECTS 298


07_CH07.fm Page 257 Wednesday, August 13, 2003 12:58 PM

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

Well begun is half done.

Proverb

Often you want to initialize some or all the member variables for an object
when you declare the object. As we will see later in this book, there are other
initializing actions you might also want to take, but initializing member vari-
ables is the most common sort of initialization. C++ includes special provi-
sions for such initializations. When you define a class you can define a special
kind of member function known as a

constructor

.

A constructor is a member
function that is automatically called when an object of that class is declared. A
constructor is used to initialize the values of some or all member variables and
to do any other sort of initialization that may be needed.


CONSTRUCTOR DEFINITIONS

You define a constructor the same way that you define any other member
function, except for two points:
7.1
constructor


07_CH07.fm Page 258 Wednesday, August 13, 2003 12:58 PM
Constructors 259

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.
void input(



);
void output(



);
void set(int newMonth, int newDay);
void set(int newMonth);
int getMonthNumber(



);
int getDay(



);
private:
int month;
int day;
};


Notice that the constructor is named

DayOfYear

, 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
promised, the above declaration will declare the object

date1

, set the value of

date1.month

to

7

, and set the value of

date1.day

to

4

. Thus, the object

date1

is initial-
ized so that it represents the date July 4. Similarly,


date2

is initialized so that it repre-
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

and

5

. The
Constructor

07_CH07.fm Page 259 Wednesday, August 13, 2003 12:58 PM
260 Constructors and Other Tools

result is conceptually equivalent to the following (although you cannot write it this way
in C++):

DayOfYear date1, date2; //PROBLEMS BUT FIXABLE
date1.DayOfYear(7, 4); //VERY ILLEGAL
date2.DayOfYear(5, 5); //VERY ILLEGAL

As the comments indicate, you cannot place the above three lines in your program. The
first line can be made to be acceptable, but the two calls to the constructor

DayOfYear

are illegal. A constructor cannot be called in the same way as an ordinary member func-
tion is called. Still, it is clear what we want to happen when we write the above three
lines, and that happens automatically when you declare the objects

date1


and

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

before the scope resolution opera-
tor

::

is the name of the class, and the

DayOfYear

after the scope resolution operator is
the name of the constructor function. Also notice that no return type is specified in the
heading of the constructor definition, not even the type

void

. Aside from these points,
a constructor can be defined in the same way as an ordinary member function.
As we just illustrated, a constructor can be defined just like any other member func-
tion. However, there is an alternative way of defining constructors that is preferable to
use. The previous definition of the constructor

DayOfYear

is completely equivalent to
the following version:
C
ONSTRUCTOR

A cc
cc
oo
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*/}

The new element shown on the second line of the constructor definition is called the

initialization section

. As this example shows, the initialization section goes after the
parenthesis that ends the parameter list and before the opening brace of the function
body. The initialization section consists of a colon followed by a list of some or all the
member variables separated by commas. Each member variable is followed by its ini-
tializing value in parentheses. Notice that the initializing values can be given in terms of
the constructor parameters.
The function body in a constructor definition with an initialization section need not
be empty as in the above example. For example, the following improved version of the
constructor definition checks to see that the arguments are appropriate:

DayOfYear::DayOfYear(int monthValue, int dayValue)
: month(monthValue), day(dayValue)
{
if ((month < 1) || (month > 12))
{
cout << "Illegal month value!\n";
exit(1);
}
if ((day < 1) || (day > 31))
{
cout << "Illegal day value!\n";
exit(1);
}

}

You can overload a constructor name like

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
initialization
section
07_CH07.fm Page 261 Wednesday, August 13, 2003 12:58 PM
262 Constructors and Other Tools
Display 7.1 Class with Constructors
(part 1 of 2)
1 #include <iostream>
2 #include <cstdlib> //for exit
3 using namespace std;
4 class DayOfYear
5 {
6 public:
7 DayOfYear(int monthValue, int dayValue);
8 //Initializes the month and day to arguments.

9 DayOfYear(int monthValue);
10 //Initializes the date to the first of the given month.

11 DayOfYear( );
12 //Initializes the date to January 1.

13 void input(
);
14 void output(
);
15 int getMonthNumber(
);

16 //Returns 1 for January, 2 for February, etc.
17 int getDay(
);
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
no parentheses.
an explicit call to the constructor
DayOfYear::DayOfYear
07_CH07.fm Page 262 Wednesday, August 13, 2003 12:58 PM

×