Absolute C++ (4th Edition) part 35 docx

10 677 0
Absolute C++ (4th Edition) part 35 docx

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

Thông tin tài liệu

344 Operator Overloading, Friends, and References 7. //Uses cstdlib: const Money operator -(const Money& amount1, const Money& amount2) { int allCents1 = amount1.cents + amount1.dollars*100; int allCents2 = amount2.cents + amount2.dollars*100; int diffAllCents = allCents1 - allCents2; int absAllCents = abs(diffAllCents); int finalDollars = absAllCents/100; int finalCents = absAllCents%100; if (diffAllCents < 0) { finalDollars = -finalDollars; finalCents = -finalCents; } return Money(finalDollars, finalCents); } 8. Add the following declaration and function definition: friend bool operator <(const Money& amount1, const Money& amount2); bool operator <(const Money& amount1, const Money& amount2) { return ((amount1.dollars < amount2.dollars) || ((amount1.dollars == amount2.dollars) && (amount1.cents < amount2.cents))); } 9. To understand why it is not circular, you need to think about the basic message of over- loading: A single function or operator name can have two or more definitions. That means that two or more different operators (or functions) can share a single name. In the line outputStream << "$-"; the operator << is the name of an operator defined in the library iostream to be used when the second argument is a quoted string. The operator named << that we define in Display 8.5 is a different operator that works when the second argument is of type Money. 10. If << and >> are to work as we want, then the first operand (first argument) must be cout or cin (or some file I/O stream). But if we want to overload the operators as members of, say, the class Money, then the first operand would have to be the calling object and so would have to be of type Money, and that is not what we want. 08_CH08.fm Page 344 Wednesday, August 13, 2003 1:02 PM Programming Projects 345 11. //Uses iostream: istream& operator >>(istream& inputStream, Percent& aPercent) { char percentSign; inputStream >> aPercent.value; inputStream >> percentSign;//Discards the % sign. return inputStream; } //Uses iostream: ostream& operator <<(ostream& outputStream, const Percent& aPercent) { outputStream << aPercent.value << ’%’; return outputStream; } 12. It is legal, but the meaning is not what you might want. (a++) increases the value of the member variables in a by one, but (a++)++ raises the value of the member variables in a++ by one, and a++ is a different object from a. (It is possible to define the increment operator so that (a++)++ will increase the value of the member variables by two but that requires use of the this pointer which is not discussed until Chapter 10.) PROGRAMMING PROJECTS 1. Modify the definition of the class Money shown in Display 8.5 so that the following are added: a. The operators <, <=, >, and >= have each been overloaded to apply to the type Money. ( Hint: See Self-Test Exercise 8.) b. The following member function has been added to the class definition. (We show the function declaration as it should appear in the class definition. The definition of the function itself will include the qualifier Money::.) const Money percent(int percentFigure) const; //Returns a percentage of the money amount in the calling object. //For example, if percentFigure is 10, then the value returned is //10% of the amount of money represented by the calling object. For example, if purse is an object of type Money whose value represents the amount $100.10, then the call purse.percent(10); returns 10% of $100.10; that is, it returns a value of type Money that represents the amount $10.01. 08_CH08.fm Page 345 Wednesday, August 13, 2003 1:02 PM 346 Operator Overloading, Friends, and References 2. Define a class for rational numbers. A rational number is a number that can be represented as the quotient of two integers. For example, 1/2, 3/4, 64/2, and so forth are all rational numbers. (By 1/2 and so on we mean the everyday fraction, not the integer division this expression would produce in a C++ program.) Represent rational numbers as two values of type int, one for the numerator and one for the denominator. Call the class Rational. Include a constructor with two arguments that can be used to set the member variables of an object to any legitimate values. Also include a constructor that has only a single parame- ter of type int; call this single parameter wholeNumber and define the constructor so that the object will be initialized to the rational number wholeNumber/1. Include a default con- structor that initializes an object to 0 (that is, to 0/1). Overload the input and output oper- ators >> and <<. Numbers are to be input and output in the form 1/2, 15/32, 300/401, and so forth. Note that the numerator, the denominator, or both may contain a minus sign, so -1/2, 15/-32, and -300/-401 are also possible inputs. Overload all the following operators so that they correctly apply to the type Rational: ==, <, <=, >, >=, +, -, *, and /. Write a test program to test your class. Hints: Two rational numbers a/b and c/d are equal if a*d equals c*b. If b and d are positive rational numbers, a/b is less than c/d provided a*d is less than c*b. You should include a function to normalize the values stored so that, after normalization, the denominator is positive and the numerator and denominator are as small as possible. For example, after normalization 4/-8 would be represented the same as -1/2. 3. Define a class for complex numbers. A complex number is a number of the form a + b*i where for our purposes, a and b are numbers of type double, and i is a number that repre- sents the quantity . Represent a complex number as two values of type double. Name the member variables real and imaginary. (The variable for the number that is multiplied by i is the one called imaginary.) Call the class Complex. Include a constructor with two parameters of type double that can be used to set the member variables of an object to any values. Include a constructor that has only a single parameter of type double; call this parameter realPart and define the constructor so that the object will be initial- ized to realPart + 0*i. Include a default constructor that initializes an object to 0 (that is, to 0 + 0*i). Overload all the following operators so that they correctly apply to the type Complex: ==, +, -, *, >>, and <<. You should also write a test program to test your class. Hints: To add or subtract two complex numbers, add or subtract the two member variables of type double. The product of two complex numbers is given by the following formula: (a + b*i)*(c + d *i) == (a*c - b*d) + (a*d + b*c)*i In the interface file, you should define a constant i as follows: const Complex i(0, 1); This defined constant i will be the same as the i discussed above. 4. (Cumulatively modify the example from Display 8.7 as follows. 1– 08_CH08.fm Page 346 Wednesday, August 13, 2003 1:02 PM a b c Programming Projects 347 a. In Display 8.7, replace the private char members first and second with an array of char of size 100 and a private data member named size. Provide a default constructor that initializes size to 10 and sets the first 10 of the char positions to ’#’. (This only uses 10 of the possible 100 slots.) Provide an accessor function that returns the value of the private member size. Test. b. Add an operator[] member that returns a char& that allows the user to access or to set any member of the private data array using a non-negative index that is less than size. Test. c. Add a constructor that takes an int argument, sz, that sets the first sz members of the char array to ’#’. Test. d. Add a constructor that takes an int argument, sz, and an array of char of size sz. The constructor should set the first sz members of the private data array to the sz members of the argument array of char. Test. NOTES: When you test, you should test with known good values, with data on boundaries and with deliberately bad values. You are not required to put checks for index out of bounds errors in your code, but that would be a nice touch. Error handling alternatives: Issue an error message then die (that is, call exit(1)) or give the user another chance to make a correct entry. 08_CH08.fm Page 347 Wednesday, August 13, 2003 1:02 PM 9 Strings 9.1 AN ARRAY TYPE FOR STRINGS 351 C-String Values and C-String Variables 351 Pitfall: Using = and == with C-strings 355 Other Functions in <cstring> 357 C-String Input and Output 360 9.2 CHARACTER MANIPULATION TOOLS 363 Character I/O 363 The Member Functions get and put 364 Example: Checking Input Using a Newline Function 366 Pitfall: Unexpected ’\n’ in Input 368 The putback , peek , and ignore Member Functions 369 Character-Manipulating Functions 372 Pitfall: toupper and tolower Return int Values 374 9.3 THE STANDARD CLASS string 375 Introduction to the Standard Class string 376 I/O with the Class string 379 Tip: More Versions of getline 382 Pitfall: Mixing cin >> variable ; and getline 383 String Processing with the Class string 384 Example: Palindrome Testing 388 Converting between string Objects and C-Strings 392 CHAPTER SUMMARY 393 ANSWERS TO SELF-TEST EXERCISES 393 PROGRAMMING PROJECTS 397 09_CH09.fm Page 349 Wednesday, August 13, 2003 1:04 PM 9 Strings Polonius: What do you read my lord? Hamlet: Words, words, words William Shakespeare, Hamlet INTRODUCTION This chapter discusses two types whose values represent strings of characters, such as "Hello" . One type is just an array with base type char that stores strings of characters in the array and marks the end of the string with the null character, ’\0’ . This is the older way of representing strings, which C++ inherited from the C programming language. These sorts of strings are called C-strings . Although C-strings are an older way of representing strings, it is difficult to do any sort of string processing in C++ without at least passing contact with C-strings. For example, quoted strings, such as "Hello" , are implemented as C-strings in C++. The ANSI/ISO C++ standard includes a more modern string handling facility in the form of the class string . The class string is the second string type that we will discuss in this chapter. The full class string uses templates and so is similar to the template classes in the Standard Template Library (STL). Templates are covered in Chapter 16 and the STL is covered in Chap- ter 19. This chapter covers basic uses of the class string that do not require a knowledge of templates. This material does not require extensive knowledge of arrays, but you should be familiar with basic array notation, such as a[i] . Section 5.1 of Chapter 5 covers more than enough material about arrays to allow you to read the material of this chapter. This material also does not require extensive knowledge of classes. Section 9.1 on C-strings and Section 9.2 on character manipulation can be covered before Chapters 6, 7, and 8, which cover classes. However, before reading Section 9.3 on the standard class string , you should read Chapter 6 and the following parts of Chapter 7: Section 7.1 and the sub- section of Section 7.2 entitled “The const Parameter Modifier” along with its accompanying pitfall section. 09_CH09.fm Page 350 Wednesday, August 13, 2003 1:04 PM An Array Type for Strings 351 An Array Type for Strings In everything one must consider the end. Jean de La Fontaine, Fables, book III (1668) This section describes one way to represent strings of characters, which C++ inherited from the C language. Section 9.3 describes a string class that is a more modern way to represent strings. Although the string type described here may be a bit “old fashioned,” it is still widely used and is an integral part of the C++ language. ■ C-STRING VALUES AND C-STRING VARIABLES One way to represent a string is as an array with base type char . However, if the string is "Hello" , it is handy to represent it as an array of characters with six indexed variables: five for the five letters in "Hello" plus one for the character ’\0’ , which serves as an end marker. The character ’\0’ is called the null character and is used as an end marker because it is distinct from all the “real” characters. The end marker allows your program to read the array one character at a time and know that it should stop reading when it reads the ’\0’ . A string stored in this way (as an array of characters terminated with ’\0’ ) is called a C-string . We spell ’\0’ with two symbols when we write it in a program, but just like the newline character ’\n’ , the character ’\0’ is really only a single character value. Like any other character value, ’\0’ can be stored in one variable of type char or one indexed variable of an array of characters. You have already been using C-strings. In C++, a literal string, such as "Hello" is stored as a C-string, although you seldom need to be aware of this detail. T HE N ULL C HARACTER , '\0' The null character, ’\0’, is used to mark the end of a C-string that is stored in an array of charac- ters. When an array of characters is used in this way, the array is often called a C-string variable. Although the null character ’\0’ is written using two symbols, it is a single character that fits in one variable of type char or one indexed variable of an array of characters. 9.1 null character, ’\0’ C-string 09_CH09.fm Page 351 Wednesday, August 13, 2003 1:04 PM 352 Strings A C-string variable is just an array of characters. Thus, the following array declara- tion provides us with a C-string variable capable of storing a C-string value with nine or fewer characters: char s[10]; The 10 is for the 9 letters in the string plus the null character ’\0’ to mark the end of the string. A C-string variable is a partially filled array of characters. Like any other partially filled array, a C-string variable uses positions starting at indexed variable 0 through as many as are needed. However, a C-string variable does not use an int variable to keep track of how much of the array is currently being used. Instead, a string variable places the special symbol ’ \0 ’ in the array immediately after the last character of the C-string. Thus, if s contains the string "Hi Mom!" , the array elements are filled as shown below: The character ’\0’ is used as a sentinel value to mark the end of the C-string. If you read the characters in the C-string starting at indexed variable s[0] , proceed to s[1], then to s[2], and so forth, you know that when you encounter the symbol ’\0’ you have reached the end of the C-string. Since the symbol ’\0’ always occupies one ele- ment of the array, the length of the longest string that the array can hold is one less than the size of the array. The thing that distinguishes a C-string variable from an ordinary array of characters is that a C-string variable must contain the null character ’\0’ at the end of the C-string value. This is a distinction regarding how the array is used rather than a distinction regarding what the array is. A C-string variable is an array of characters, but it is used in a different way. You can initialize a C-string variable when you declare it, as illustrated by the follow- ing example: char myMessage[20] = "Hi there."; Notice that the C-string assigned to the C-string variable need not fill the entire array. When you initialize a C-string variable, you can omit the array size and C++ will automatically make the size of the C-string variable one more than the length of the quoted string. (The one extra indexed variable is for ’\0’.) For example: char shortString[] = "abc"; is equivalent to char shortString[4] = "abc"; C-string variables s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] s[9] H i M o m ! \0? ? C-string variables vs. arrays of characters initializing C-string variables 09_CH09.fm Page 352 Wednesday, August 13, 2003 1:04 PM An Array Type for Strings 353 Be sure you do not confuse the following initializations: char shortString[] = "abc"; and char shortString[] = {’a’, ’b’, ’c’}; They are not equivalent. The first of these two possible initializations places the null character ’\0’ in the array after the characters ’a’, ’b’, and ’c’. The second one does not put a ’\0’ anyplace in the array. C-S TRING V ARIABLE D ECLARATION A C-string variable is the same thing as an array of characters, but it is used differently. A C-string variable is declared to be an array of characters in the usual way. S YNTAX char Array_Name [ Maximum_C-string_Size + 1]; E XAMPLE char myCstring[11]; The + 1 allows for the null character ’\0’, which terminates any C-string stored in the array. For example, the C-string variable myCstring in the above example can hold a C-string that is ten or fewer characters long. I NITIALIZING A C-S TRING V ARIABLE A C-string variable can be initialized when it is declared, as illustrated by the following example: char yourString[11] = "Do Be Do"; Initializing in this way automatically places the null character, ’\0’, in the array at the end of the C-string specified. If you omit the number inside the square brackets, [], then the C-string variable will be given a size one character longer than the length of the C-string. For example, the following declares myString to have nine indexed variables (eight for the characters of the C-string "Do Be Do" and one for the null character ’\0’): char myString[] = "Do Be Do"; 09_CH09.fm Page 353 Wednesday, August 13, 2003 1:04 PM 354 Strings A C-string variable is an array, so it has indexed variables that can be used just like those of any other array. For example, suppose your program contains the following C- string variable declaration: char ourString[5] = "Hi"; With ourString declared as above, your program has the following indexed variables: ourString[0], ourString[1], ourString[2], ourString[3], and ourString[4]. For example, the following will change the C-string value in ourString to a C-string of the same length consisting of all ’X’ characters: int index = 0; while (ourString[index] != ’\0’) { ourString[index] = ’X’; index++; } When manipulating these indexed variables you should be very careful not to replace the null character ’\0’ with some other value. If the array loses the value ’\0’ it will no longer behave like a C-string variable. For example, the following will change the array happyString so that it no longer contains a C-string: char happyString[7] = "DoBeDo"; happyString[6] = ’Z’; After the above code is executed, the array happyString will still contain the six letters in the C-string "DoBeDo", but happyString will no longer contain the null character ’\0’ to mark the end of the C-string. Many string-manipulating functions depend crit- ically on the presence of ’\0’ to mark the end of the C-string value. As another example, consider the above while loop that changes characters in the C-string variable ourString. That while loop changes characters until it encounters a ’\0’. If the loop never encounters a ’\0’, then it could change a large chunk of mem- ory to some unwanted values, which could make your program do strange things. As a safety feature, it would be wise to rewrite the above while loop as follows, so that if the null character ’\0’ is lost, the loop will not inadvertently change memory locations beyond the end of the array: int index = 0; while ( (ourString[index] != ’\0’) && (index < SIZE) ) { ourString[index] = ’X’; index++; } SIZE is a defined constant equal to the declared size of the array ourString. indexed variables for C-string variables Do not destroy the ’\0’. 09_CH09.fm Page 354 Wednesday, August 13, 2003 1:04 PM . Strings 9.1 AN ARRAY TYPE FOR STRINGS 351 C-String Values and C-String Variables 351 Pitfall: Using = and == with C-strings 355 Other Functions in <cstring> 357 C-String Input and Output. processing in C++ without at least passing contact with C-strings. For example, quoted strings, such as "Hello" , are implemented as C-strings in C++. The ANSI/ISO C++ standard. single parameter of type double; call this parameter realPart and define the constructor so that the object will be initial- ized to realPart + 0*i. Include a default constructor that initializes

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

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan