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

A Complete Guide to Programming in C++ part 44 doc

10 207 0

Đ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 222,38 KB

Nội dung

4 1 1Overloading Operators Overloading operators allows you to apply existing operators to objects of class type.. Arithmetic operators, comparisons, the subscript operator, and the shif

Trang 1

S O L U T I O N S 409

inline void go_on()

{

cout << "\n\nGo on with return! ";

cin.sync(); cin.clear(); // No previous input

while( cin.get() != '\n')

;

}

int menu(); // Enter a command

char askForSave(); // Prompt user to save

char header[] =

"\n\n * * * * * Telephone List * * * * *\n\n";

TelList myFriends; // A telephone list

int main()

{

int action = 0; // Command

string name; // Read a name

while( action != 'Q')

{

action = menu();

cls(); cout << header << endl;

switch( action)

{

//

-// case 'S': case 'F': case 'A': case 'D':

// unchanged (refer to the solutions of chapter 16)

//

-case 'O': // To open a file

if(myFriends.isDirty() && askForSave() == 'y')

myFriends.save();

if( myFriends.load())

cout << "Telephone list read from file "

<< myFriends.getFilename() <<"!"

<< endl;

else

cerr << "Telephone list not read!"

<< endl;

go_on();

break;

case 'U': // Save as

if( myFriends.saveAs())

cout << "Telephone list has been saved in file: "

<< myFriends.getFilename() << " !" <<endl;

else

cerr << "Telephone list not saved!" << endl;

go_on();

break;

Trang 2

410 C H A P T E R 1 8 F U N D A M E N T A L S O F F I L E I N P U T A N D O U T P U T

case 'W': // Save if( myFriends.save())

cout << "Telephone list has been saved in "

<< "the file "

<< myFriends.getFilename() << endl;

else cerr << "Telephone list not saved!"

<< endl;

go_on();

break;

case 'Q': // Quit if( myFriends.isDirty() && askForSave() == 'Y') myFriends.save();

cls();

break;

} } // End of while return 0;

}

int menu() {

static char menuStr[] = //

"\n -"

"\n O = Open a file"

"\n W = Save "

"\n U = Save as "

"\n -"

"\n Q = Quit the program"

"\n\n Your choice: ";

// -// everything else unchanged (cf solutions in Chapter 16) // -return choice;

}

char askForSave() {

char c;

cout << "Do you want to save the phone list(y/n)? "; do

{ cin.get(c);

c = toupper(c);

}while( c != 'Y' && c != 'N');

return c;

}

Trang 3

4 1 1

Overloading Operators

Overloading operators allows you to apply existing operators to objects

of class type For example, you can stipulate the effect of the + operator for the objects of a particular class

This chapter describes various uses of overloaded operators

Arithmetic operators, comparisons, the subscript operator, and the shift operators for input and output are overloaded to illustrate the

appropriate techniques

The concept of friend functions, which is introduced in this context, is particularly important for overloading operators

Trang 4

412 C H A P T E R 1 9 O V E R L O A D I N G O P E R A T O R S

The assignment operator =, the address operator &, and the comma operator, have a predefined meaning for each built-in type This meaning can be changed for classes by a definition of your own

GENERALS

Overloadable operators

䊐 Rules

An operator is always overloaded in conjunction with a class The definition scope of an operator is simply extended—the characteristics of the operator remain unchanged The following rules apply:

■ You cannot create “new operators”—that is, you can only overload existing oper-ators

■ You cannot redefine the operators for fundamental types

■ You cannot change the operands of an operator A binary operator will always be binary and a unary operator will always be unary

■ The precedence and the order of grouping operators of the same precedence remains unchanged

+ - * / %

== != < <= > >=

& | ^ ~ << >>

&& || !

= op=

() []

& * -> , new delete

++

Arithmetic operators

Relational operators

Logical operators Assignment operators ( op is a binary arithmetic

or a binary bitwise operator)

Bitwise operators

Function call, subscript operator Other operators

Operators Meaning

Trang 5

G E N E R A L S 413

䊐 Overloading

An operator is said to be overloaded if it is defined for multiple types In other words, overloading an operator means making the operator significant for a new type

Most operators are already overloaded for fundamental types In the case of the expression:

Example: a / b

the operand type determines the machine code created by the compiler for the division operator If both operands are integral types, an integral division is performed; in all other cases floating-point division occurs Thus, different actions are performed depend-ing on the operand types involved

䊐 Operators for Classes

In addition to defining methods, C++ offers the interesting possibility of defining the functionality of a class by means of operators Thus, you can overload the + operator instead of, or in addition to, using the add()method For the objects xandyin this class:

x + y is equivalent to x.add(y)

Using the overloaded operators of a class expressions of this type can be as easily defined

as for fundamental types Expressions using operators are often more intuitive, and thus easier to understand than expressions containing function calls

Many operators belonging to the C++ standard library classes are already overloaded This applies to the stringclass, with which you are already familiar

Example: string str1("Hello "), str2("Eve");

str1 += str2; // Operator +=

if( str2 < "Alexa") // Operator <

cout << str1; // Operator <<

str2[2] = 'i'; // Operators [] and =

The tables on the opposite page show those operators that can be overloaded Some operators cannot be overloaded, such as the cast operators, the sizeof operator, and the following four operators:

:: * member access and scope resolution operators

?: conditional operator

These operators either have a fixed significance in the classes for which they are defined,

or overloading the operator makes no sense

Trang 6

414 C H A P T E R 1 9 O V E R L O A D I N G O P E R A T O R S

// DayTime.h // The class DayTime containing operators < and ++ //

-#ifndef _DAYTIME_

#define _DAYTIME_

class DayTime {

private:

short hour, minute, second;

bool overflow;

public:

DayTime( int h = 0, int m = 0, int s = 0);

bool setTime(int hour, int minute, int second = 0); int getHour() const { return hour; }

int getMinute() const { return minute; } int getSecond() const { return second; } int asSeconds() const // Daytime in seconds { return (60*60*hour + 60*minute + second); } bool operator<( const DayTime& t) const // compare { // *this and t return asSeconds() < t.asSeconds();

} DayTime& operator++() // Increment seconds {

++second; // and handle overflow return *this;

} void print() const;

};

#endif // _DAYTIME_

#include "DayTime.h"

DayTime depart1( 11, 11, 11), depart2(12,0,0);

if( depart1 < depart2 ) cout << "\nThe 1st plane takes off earlier!" << endl;

OPERATOR FUNCTIONS (1)

Operators < and ++ for class DayTime

Calling the Operator <

Trang 7

O P E R A T O R F U N C T I O N S ( 1 ) 415

䊐 Naming Operator Functions

To overload an operator, you just define an appropriate operator function The operator

function describes the actions to be performed by the operator The name of an operator function must begin with the operatorkeyword followed by the operator symbol

Example: operator+

This is the name of the operator function for the + operator

An operator function can be defined as a global function or as a class method Gener-ally, operator functions are defined as methods, especially in the case of unary operators However, it can make sense to define an operator function globally This point will be illustrated later

䊐 Operator Functions as Methods

If you define the operator function of a binary operator as a method, the left operand will

always be an object of the class in question The operator function is called for this object The second, right operand is passed as an argument to the method The method

thus has a single parameter.

Example: bool operator<( const DayTime& t) const;

In this case the lesser than operator is overloaded to compare two DayTimeobjects It replaces the method isLess(), which was formerly defined for this class

The prefix operator ++has been overloaded in the example on the opposite page to illustrate overloading unary operators The corresponding operator function in this class has no parameters The function is called if the object a in the expression ++a is an object of class DayTime

䊐 Calling an Operator Function

The example opposite compares two times of day:

Example: depart1 < depart2

The compiler will attempt to locate an applicable operator function for this expression and then call the function The expression is thus equivalent to

depart1.operator<( depart2)

Although somewhat uncommon, you can call an operator function explicitly The previ-ous function call is therefore technically correct

Programs that use operators are easier to encode and read However, you should be aware of the fact that an operator function should perform a similar operation to the cor-responding operator for the fundamental type Any other use can lead to confusion

Trang 8

416 C H A P T E R 1 9 O V E R L O A D I N G O P E R A T O R S

// Euro1.h : The class Euro containing arithmetic operators //

-#ifndef _EURO_H_

#define _EURO_H_

#include <sstream> // The class stringstream

#include <iomanip>

using namespace std;

class Euro

{ private:

long data; // Euros * 100 + Cents public:

Euro( int euro = 0, int cents = 0)

{ data = 100L * (long)euro + cents;

}

Euro( double x)

{

x *= 100.0; // Rounding, data = (long)(x>=0.0 ? x+0.5 : x-0.5); //ex 9.7 -> 10 }

long getWholePart() const { return data/100; } int getCents() const { return (int)(data%100); } double asDouble() const { return (double)data/100.0; } string asString() const; // Euro as string.

void print( ostream& os) const // Output to stream os { os << asString() << " Euro" << endl; }

// Operator functions Euro operator-() const // Negation (unary minus)) {

Euro temp;

temp.data = -data;

return temp;

} Euro operator+ ( const Euro& e2) const // Addition {

Euro temp;

temp.data = data + e2.data;

return temp;

} Euro operator-( const Euro& e2) const // Subtraction { /* Analog just as operator + */ }

Euro& operator+=( const Euro& e2) // Add Euros {

data += e2.data;

return *this;

} Euro& operator-=( const Euro& e2); // Subtract euros { /* Just as operator += */ }

};

// Continued on the next double page.

OPERATOR FUNCTIONS(2)

Class Euro

Trang 9

O P E R A T O R F U N C T I O N S ( 2 ) 417

䊐 Notes on the Sample Class Euro

The opposite page shows the Euroclass, which represents the new European currency The member datastores a given amount of euros as an integer in the format:

(integer part)*100 + Cents

Thusdata/100returns the number of euros and data%100the number of cents This technique allows for easy implementation of the arithmetic operations needed for the

Euroclass

In addition to a constructor that is passed whole euros and cents as arguments, there is

a constructor that can process a doublevalue of euros and a standard copy constructor

Example: Euro e1(9,50), e2(20.07), e3(-e1);

䊐 Negation, Addition, and Subtraction

The unary operator -does not change its operand In the previous example, e3is thus assigned a value of -9,50 euro, but e1remains unchanged The operator function is thus a constmethod that creates and returns a temporary object

The binary operators +and-do not change their operands either Thus, the operator functions also create temporary objects and return them with the correct values

Example: Euro sum = e1 + e2;

The expression e1 + e2results in e1.operator+(e2) The return value is used to initialize the new object, sum

䊐 The += and -= Operators

Although the operators +and-were overloaded for the Euroclass, this does not auto-matically mean that the operators +=and-=are overloaded Both are distinct operators that require separate definitions Of course, you should overload the operators to ensure that the statements

Example: sum += e3; and sum = sum + e3;

produce the same results

The binary operators +=and-=change the current object, that is, the left operand A temporary object is not required! The expression sum += e3represents the current object after modification Thus, the operator function returns a reference to *this

Trang 10

418 C H A P T E R 1 9 O V E R L O A D I N G O P E R A T O R S

// Continues file Euro1.h // -inline string Euro::asString() const // Euro as string {

stringstream strStream; // Stream for conversion long temp = data;

if( temp < 0) { strStream << '-'; temp = -temp; } strStream << temp/100 << ','

<< setfill('0') << setw(2) << temp%100; return strStream.str();

}

#endif // _EURO_H_

// Euro1_t.cpp // Tests the operators of class Euro

//

-#include "Euro1.h" // Definition of the class

#include <iostream>

using namespace std;

int main() {

cout << "* * * Testing the class Euro * * *\n" << endl; Euro wholesale( 20,50), retail;

retail = wholesale; // Standard assignment retail += 9.49; // += (Euro)9.49

cout << "Wholesale price: "; wholesale.print(cout); cout << "Retail price: "; retail.print(cout);

Euro discount( 2.10); // double-constructor retail -= discount;

cout << "\nRetail price including discount: ";

retail.print(cout);

wholesale = 34.10;

cout << "\nNew wholesale price: ";

wholesale.print(cout);

Euro profit( retail - wholesale); // Subtraction and

// copy constructor cout << "\nThe profit: ";

profit.print(cout); // Negative!

return 0;

}

USING OVERLOADED OPERATORS File Euro1.h continued

Sample program

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN

w