1. Trang chủ
  2. » Công Nghệ Thông Tin

Absolute C++ (4th Edition) part 30 pdf

10 1,4K 1

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 313,91 KB

Nội dung

Elements are added to a vector using the member function push_back , as illustrated below: v.push_back42; Once an element position has received its first element, either with push_back o

Trang 1

The vector definition is given in the library vector, which places it in the std namespace Thus, a file that uses vectors would include the following (or something similar):

#include <vector>

using namespace std;

U SING S QUARE B RACKETS BEYOND THE V ECTOR S IZE

If v is a vector and i is greater than or equal to v.size( ) , then the element v[i] does not yet exits and needs to be created by using push_back to add elements up to and including position

i If you try to set v[i] for i greater than or equal to v.size( ) , as in

v[i] = n;

then you may or may not get an error message, but your program will undoubtedly misbehave at some point.

V ECTORS

Vectors are used very much like arrays, but a vector does not have a fixed size If it needs more capacity to store another element, its capacity is automatically increased Vectors are defined in the library vector , which places them in the std namespace Thus, a file that uses vectors would include the following lines:

#include <vector>

using namespace std;

The vector class for a given Base_Type is written vector< Base_Type > Two sample vector decla-rations are as follows:

vector< int > v; //default constructor producing an empty vector.

vector<AClass> record(20); //vector constructor uses the //default constructor for AClass to initialize 20 elements.

Elements are added to a vector using the member function push_back , as illustrated below:

v.push_back(42);

Once an element position has received its first element, either with push_back or with a con-structor initialization, that element position can then be accessed using square bracket notation, just like an array element.

Trang 2

294 Constructors and Other Tools

Tip V ECTOR A SSIGNMENT I S W ELL B EHAVED

The assignment operator with vectors does an element-by-element assignment to the vector on the left-hand side of the assignment operator (increasing capacity if needed and resetting the size of the vector on the left-hand side of the assignment operator) Thus, provided the assign-ment operator on the base type makes an independent copy of an eleassign-ment of the base type, then the assignment operator on the vector will make an independent copy, not an alias, of the vector

on the right-hand side of the assignment operator

Note that for the assignment operator to produce a totally independent copy of the vector on the right-hand side of the assignment operator requires that the assignment operator on the base type make completely independent copies The assignment operator on a vector is only as good (or bad) as the assignment operator on its base type.

At any point in time a vector has a capacity, which is the number of elements for which

it currently has memory allocated The member function capacity( ) can be used to find out the capacity of a vector Do not confuse the capacity of a vector with the size of

a vector The size is the number of elements in a vector, whereas the capacity is the number of elements for which there is memory allocated Typically the capacity is larger than the size, and the capacity is always greater than or equal to the size Whenever a vector runs out of capacity and needs room for an additional member, the capacity is automatically increased The exact amount of the increase is implemen-tation dependent, but always allows for more capacity than is immediately needed A commonly used implementation scheme is for the capacity to double whenever it needs

to increase Because increasing capacity is a complex task, this approach of reallocating capacity in large chunks is more efficient than allocating numerous small chunks You can completely ignore the capacity of a vector and that will have no effect on what your program does However, if efficiency is an issue, you may want to manage capacity yourself and not simply accept the default behavior of doubling capacity whenever more is needed You can use the member function reserve to explicitly increase the capacity of a vector For example,

v.reserve(32);

sets the capacity to at least 32 elements, and v.reserve(v.size( ) + 10);

sets the capacity to at least 10 more than the number of elements currently in the vec-tor Note that you can rely on v.reserve to increase the capacity of a vector, but it does not necessarily decrease the capacity of a vector if the argument is smaller than the cur-rent capacity

capacity

Trang 3

Self-Test Exercises

You can change the size of a vector using the member function resize For example, the following resizes a vector to 24 elements:

v.resize(24);

If the previous size were less than 24, then the new elements are initialized as we described for the constructor with an integer argument If the previous size were greater than 24, then all but the first 24 elements are lost The capacity is automatically increased if need be Using resize and reserve, you can shrink the size and capacity of

a vector when there is no longer any need for some elements or some capacity

9 Is the following program legal? If so, what is the output?

#include <iostream>

#include <vector>

using namespace std;

int main( ) {

vector< int > v(10);

int i;

for (i = 0; i < v.size( ); i++) v[i] = i;

vector< int > copy;

copy = v;

v[0] = 42;

for (i = 0; i < copy.size( ); i++) cout << copy[i] << " ";

cout << endl;

return 0;

}

10 What is the difference between the size and the capacity of a vector?

S IZE AND C APACITY The size of a vector is the number of elements in the vector The capacity of a vector is the number

of elements for which it currently has memory allocated For a vector v , the size and capacity can

be recovered with the member functions v.size( ) and v.capacity( )

Trang 4

296 Constructors and Other Tools

A constructor is a member function of a class that is called automatically when an

object of the class is declared A constructor must have the same name as the class of which it is a member

A default constructor is a constructor with no parameters You should always

define a default constructor for your classes

■ A member variable for a class may itself be of a class type If a class has a class mem-ber variable, then the memmem-ber variable constructor can be invoked in the initializa-tion secinitializa-tion of the outer class constructor

■ A constant call-by-reference parameter is more efficient than a call-by-value parame-ter for class type parameparame-ters

■ Making very short function definitions inline can improve the efficiency of your code

■ Static member variables are variables that are shared by all objects of a class

■ Vector classes have objects that behave very much like arrays whose capacity to hold elements will automatically increase if more capacity is needed

ANSWERS TO SELF-TEST EXERCISES

1.YourClass anObject(42, ’A’); //LEGAL YourClass anotherObject; //LEGAL YourClass yetAnotherObject( ); //PROBLEM anObject = YourClass(99, ’B’); //LEGAL anObject = YourClass( ); //LEGAL anObject = YourClass; //ILLEGAL

The statement marked //PROBLEM is not strictly illegal, but it does not mean what you might think it means If you mean this to be a declaration of an object called

yetAnotherObject, then it is wrong It is a correct declaration for a function called

yetAnotherObject that takes zero arguments and that returns a value of type YourClass, but that is not usually the intended meaning As a practical matter, you can probably consider it illegal The correct way to declare an object called yetAnotherObject so that it will be initialized with the default constructor is as follows:

YourClass yetAnotherObject;

2 A default constructor is a constructor that takes no arguments Not every class has a default constructor If you define absolutely no constructors for a class, then a default constructor will be automatically provided On the other hand, if you define one or more constructors but do not define a default constructor, then your class will have no default constructor Chapter Summary

Trang 5

3 The definition is easier to give if you also add a private helping function named BankAc-count::digitToInt, as below, to the class BankAccount

//Uses iostream:

void BankAccount::input( ) {

int dollars;

char point, digit1, digit2;

cout <<

"Enter account balance (include cents even if 00) $";

cin >> dollars;

cin >> point >> digit1 >> digit2;

accountDollars = dollars;

accountCents = digitToInt(digit1)*10 + digitToInt(digit2);

if (accountDollars < 0) accountCents = -accountCents;

cout << "Enter interest rate (NO percent sign): ";

cin >> rate;

setRate(rate);

}

int BankAccount::digitToInt( char digit) {

return ( static_cast < int >(digit) - static_cast < int >(’0’));

}

4 The member function input changes the value of its calling object, and so the compiler will issue an error message if you add the const modifier

5 Similarities: Each parameter call method protects the caller’s argument from change Dif-ferences: If the type is a large structure or class object, a call by value makes a copy of the caller’s argument and thus uses more memory than a call by constant reference

6 In const int x = 17;, the const keyword promises the compiler that code written by the author will not change the value of x

In the int f( ) const ; declaration, the const keyword is a promise to the compiler that code written by the author to implement function f will not change anything in the calling object

In int g( const A& x);, the const keyword is a promise to the compiler that code written by the class author will not change the argument plugged in for x

7.class DayOfYear {

public : DayOfYear( int monthValue, int dayValue);

DayOfYear( int monthValue);

DayOfYear( );

Trang 6

298 Constructors and Other Tools

void input( );

void output( );

int getMonthNumber( ) { return month; } int getDay( ) { return day; }

private : int month;

int day;

void testDate( );

};

8 No, it cannot be a static member function because it requires a calling object for the mem-ber variable name

9 The program is legal The output is

0 1 2 3 4 5 6 7 8 9

Note that changing v does not change copy A true independent copy is made with the assignment

copy = v;

10 The size is the number of elements in a vector, while the capacity is number of elements for which there is memory allocated Typically the capacity is larger than the size

PROGRAMMING PROJECTS

1 Define a class called Month that is an abstract data type for a month Your class will have one member variable of type int to represent a month (1 for January, 2 for February, and

so forth) Include all the following member functions: a constructor to set the month using the first three letters in the name of the month as three arguments, a constructor to set the month using an integer as an argument (1 for January, 2 for February, and so forth), a default constructor, an input function that reads the month as an integer, an input func-tion that reads the month as the first three letters in the name of the month, an output function that outputs the month as an integer, an output function that outputs the month

as the first three letters in the name of the month, and a member function that returns the next month as a value of type Month Embed your class definition in a test program

2 Redefine the implementation of the class Month described in Programming Project 1 (or

do the definition for the first time, but do the implementation as described here) This time the month is implemented as three member variables of type char that store the first three letters in the name of the month Embed your definition in a test program

3 My mother always took a little red counter to the grocery store The counter was used to keep tally of the amount of money she would have spent so far on that visit to the store if she bought everything in the basket The counter had a four-digit display, increment but-tons for each digit, and a reset button An overflow indicator came up red if more money was entered than the $99.99 it would register (This was a long time ago.)

1

7

6

Trang 7

Write and implement the member functions of a class Counter that simulates and slightly generalizes the behavior of this grocery store counter The constructor should create a

Counter object that can count up to the constructor’s argument That is, Counter(9999)

should provide a counter that can count up to 9999 A newly constructed counter displays

a reading of 0 The member function void reset( ); sets the counter’s number to 0 The member function void incr1( ); increments the units digits by 1, void incr10( );

increments the tens digit by 1, and void incr100( ); and void incr1000( ); increment the next two digits, respectively Accounting for any carrying when you increment should require no further action than adding an appropriate number to the private data member

A member function bool overflow( ); detects overflow (Overflow is the result of incrementing the counter’s private data member beyond the maximum entered at counter construction.)

Use this class to provide a simulation of my mother’s little red clicker Even though the display is an integer, in the simulation, the rightmost (lower order) two digits are always thought of as cents and tens of cents, the next digit is dollars, and the fourth digit is tens of dollars

Provide keys for cents, dimes, dollars, and tens of dollars Unfortunately, no choice of keys seems particularly mnemonic One choice is to use the keys asdfo: a for cents, followed by

a digit 1 to 9; s for dimes, followed by a digit 1 to 9; d for dollars, followed by a digit 1 to

9; and f for tens of dollars, again followed by a digit 1 to 9 Each entry (one of asdf

followed by 1 to 9) is followed by pressing the Return key Any overflow is reported after each operation Overflow can be requested by pressing the o key

7.4

For additional online

Programming Projects,

click the CodeMate icons

below

Trang 8

8 Operator Overloading, Friends, and References

8.1 BASIC OPERATOR OVERLOADING 302

Overloading Basics 303 Tip: A Constructor Can Return an Object 308 Returning by const Value 309

Tip: Returning Member Variables of a Class Type 312 Overloading Unary Operators 313

Overloading as Member Functions 314 Tip: A Class Has Access to All Its Objects 316 Overloading Function Application ( ) 317 Pitfall: Overloading && , || , and the Comma Operator 317

8.2 FRIEND FUNCTIONS AND AUTOMATIC TYPE CONVERSION 318

Constructors for Automatic Type Conversion 318 Pitfall: Member Operators and Automatic Type Conversion 319 Friend Functions 320

Pitfall: Compilers without Friends 323 Friend Classes 323

8.3 REFERENCES AND MORE OVERLOADED OPERATORS 324

References 325 Pitfall: Returning a Reference to Certain Member Variables 327 Overloading >> and << 327

Tip: What Mode of Returned Value to Use 335 The Assignment Operator 336

Overloading the Increment and Decrement Operators 337 Overloading the Array Operator [ ] 337

Overloading Based on L-Value versus R-Value 341

CHAPTER SUMMARY 342 ANSWERS TO SELF-TEST EXERCISES 342 PROGRAMMING PROJECTS 345

08_CH08.fm Page 301 Wednesday, August 13, 2003 1:02 PM

Trang 9

8 Operator Overloading, Friends, and References

Eternal truths will be neither true nor eternal unless they have fresh meaning for every new social situation.

Franklin D Roosevelt, Address at the University of Pennsylvania

[September 20, 1940]

INTRODUCTION

This chapter discusses a number of tools to use when defining classes The first tool is operator overloading, which allows you to overload operators, such as + and ==, so that they apply to objects of the classes you define The second tool

is the use of friend functions which are functions that are not members of a class but still have access to the private members of the class This chapter also discusses how to provide automatic type conversion from other data types to the classes you define

If you have not yet covered arrays (Chapter 5), you should skip the subsec-tion of 8.3 entitled Overloading the Array Operator [ ] It covers a topic that may not make sense unless you know about array basics

Basic Operator Overloading

He’s a smooth operator.

Line from a song by Sade (written by Sade Adu and Ray St John)

Operators such as +, -, %, ==, and so forth are nothing but functions that are used with a slightly different syntax We write x + 7 rather than +(x, 7), but the + operator is a function that takes two arguments (often called operands

rather than arguments) and returns a single value As such, operators are not really necessary We could make do with +(x, 7) or even add(x, 7) Oper-ands are an example of what is often called syntactic sugar, meaning a slightly different syntax that people like However, people are very comfortable with the usual operator syntax, x + 7, that C++ uses for types such as int and dou-ble And one way to view a high-level language, such as C++, is as a way to make people comfortable with programming computers Thus, this syntactic sugar is probably a good idea; at the least, it is a well-entrenched idea In C++ you can overload the operators, such as + and ==, so that they work with oper-ands in the classes you define The way to overload an operator is very similar

to the way you overload a function name The details are best explained through an example

8.1

operators and

functions

operand

syntactic

sugar

Trang 10

Basic Operator Overloading 303

Display 8.1 contains the definition of a class whose values are amounts of U.S money, such as $9.99 or $1567.29 The class has a lot in common with the BankAccount class

we defined in Display 7.2 It represents amounts of money in the same way, as two ints for the dollars and cents parts It has the same private helping functions Its construc-tors and accessor and mutator functions are similar to those of the class BankAccount What is truly new about this Money class is that we have overloaded the plus sign and the minus sign so they can be used to add or subtract two objects of the class Money, and we have overloaded the == sign so it can be used to compare two objects of the class Money to see if they represent the same amount of money Let’s look at these overloaded operators

You can overload the operator + (and many other operators) so that it will accept arguments of a class type The difference between overloading the + operator and defin-ing an ordinary function involves only a slight change in syntax: You use the symbol +

as the function name and precede the + with the keyword operator The operator dec-laration (function decdec-laration) for the plus sign is as follows:

const Money operator +( const Money& amount1, const Money& amount2);

The operands (arguments) are both constant reference parameters of type Money The operands can be of any type, as long as at least one is a class type In the general case, operands may be call-by-value or call-by-reference parameters and may have the const modifier or not However, for efficiency reasons, constant call by reference is usually used in place of call by value for classes In this case the value returned is of type Money, but in the general case the value returned can be of any type, including void The const before the returned type Money will be explained later in this chapter For now, you can safely ignore that const

Note that the overloaded binary operators + and - are not member operators (mem-ber functions) of the class Money and therefore do not have access to the private mem-bers of the class Money That is why the definition for the overloaded operators uses accessor and mutator functions Later in this chapter we will see other ways of over-loading an operand, including overover-loading it as a member operator Each of the differ-ent ways of overloading an operator has its advantages and disadvantages

The definitions of the overloaded binary operators + and - are perhaps a bit more complicated than you might expect The extra details are there to cope with the fact that amounts of money can be negative

The unary minus sign operator - is discussed in the subsection Overloading Unary Operators, later in this chapter

The operator == is also overloaded so that it can be used to compare two objects of the class Money Note that the type returned is bool so that == can be used to make comparisons in the usual ways, such as in an if-else statement

how to overload

an operator

Ngày đăng: 04/07/2014, 05:21

TỪ KHÓA LIÊN QUAN

w