510 likes | 528 Views
Lecture 7. Overloading Operators. COSC 1567 C++ Programming. Objectives. The benefits of overloading The rules that apply to operator overloading Overload math operators Overload operators to work with a class object and a primitive object
E N D
Lecture 7 Overloading Operators COSC 1567 C++ Programming
Objectives • The benefits of overloading • The rules that apply to operator overloading • Overload math operators • Overload operators to work with a class object and a primitive object • Chain multiple mathematical operations in a statement
Objectives • Overload the insertion (<<) operator for output • Overload the extraction operator (>>) for input • Overload the prefix and postfix ++ and -- operators • Overload the == operator • Overload the = operator • Overload the subscript and parentheses operators
Understanding the Benefits of Overloading • Having more than one function with the same name is beneficial because you can use one easy-to-understand function name without paying attention to the data types involved • Polymorphism allows the same operation to be carried out differently, depending on the object • Purists find a subtle difference between overloading and polymorphism • Some reserve the term polymorphism (or pure polymorphism) for situations in which one function body is used with a variety of arguments
Using the + Operator Polymorphically • Separate actions can result from what seems to be the same operation or command • The + operator has a variety of meanings, which include: • Alone before a value (called unary form), + indicates a positive values, as in the expression +7 • Between two integers (called binary form), + indicates integer addition, as in the expression 5+ 9 • Between two floating-point numbers (also called binary form), + indicates floating-point addition, as in the expression 6.4 + 2.1
Overloading Operators—The Rules • Operator overloading is the process by which you apply operators to your own abstract data types • The +, -, *, and / symbols make it easy to work with built-in data types such as int and double • Classes, however, contain a variety of data members • As a result, if you want the compiler to perform arithmetic with two class objects, you must tell the compiler what you mean • Good programming style dictates that you endow the operator with a reasonable meaning
Overloading Operators—The Rules • You overload an operator by making it a function; subsequently, you can use it just like any other function • C++ operators are classified as unary or binary, depending on whether they take one or two arguments, respectively
Overloading Operators—The Rules • Associativity refers to the order in which actions within an expression are carried out • You cannot change associativity when you overload operators • You also cannot change the normal precedence of any operator
Overloading Math Operators • When you code an expression such as 4 + 7, C++ understands that you intend to carry out binary integer addition because of the context of the + symbol • When you code an expression such as regularSal + bonus, if C++ can recognize regularSal and bonus as declared double variables, then floating-point addition takes place • The name of the operator function that overloads the + symbol is operator+()
Overloading Math Operators Ex7-1.cpp
Overloading Math Operators • The operator+() function in Figure 8-1 can work like any other member function • When you examine the code for the addTwo() and operator+() functions in Figure 8-1, you see that the only difference is the function name • Instead of the awkward sum = clerk.operator+(driver);, the operator+() function allows you to leave off the word operator in the function name and add either of the following statements: sum = clerk + driver; sum = driver + clerk;
Paying Attention to the Order of the Operands • You can choose to overload any of the arithmetic operators for any classes you develop • Then you can use the corresponding operator symbol in a natural way with class objects
Paying Attention to the Order of the Operands Ex7-2.cpp • Create a class for a SalesOffice • The class will include an overloaded division operator (operator /) so you can divide one office’s sales by another to determine the ratio of their sales
Overloading an Operator to Work with a Class Object and a Primitive Type Ex7-3.cpp • When you add two objects using the + operator, the objects do not have to be the same type • You can add an integer and a double with an expression such as 5 + 7.84
Overloading an Operator to Work with a Class Object and a Primitive Type • You cannot overload operators that work with C++’s built-in data types • You cannot overload the + that works with two doubles to make it do anything but add two doubles • Similarly, you can’t overload operators whose first operand is an object that is a built-in type, even if the second operand is a class object
Using Multiple Operations in a Statement • Most modern programming languages allow several operators to be used in the same statement • If you want to sum three values in an older programming language such as assembler, you first must add two values, producing a temporary total • Then, in a separate statement, you add the third value to that total
Program that Adds Three Sale Objects Ex7-4.cpp
Using Multiple Operations in a Statement • When the Sale class operator+() function does not return a double, but instead returns an object of Sale type (as shown in Figure 8-8), the multiple addition works correctly • The sequence of events now occurs as follows: 1. The left-most + operator is encountered, and C++ recognizes a Sale object on each side of the + symbol. The overloaded operator+() function is called, and saleAmounts for a Shirt and a Tie are added 2. The next + operator is encountered. A Sale object now is found on each side of the +—the temporary object returned by the first addition, and the pants object 3. The temporary object is assigned to the total Sale object
Using Multiple Operations in a Statement • The results of the execution of the program in Figure 8-9 are shown in Figure 8-10 • C++ forces you to use the built-in precedence rules for your class operators • If you want to be able to add either a double or a Sale object to a Sale object, then simply write both versions of the overloaded operator for the class
Overloading Output • The << operator also is overloaded by C++ • It is both a bitwise left-shift operator and an output operator; it is called the insertion operator when used for output • The << operator acts as an output operator only when cout (or another output stream object) appears on the left side • When you use cout in a program, you must include #include<iostream> • The preceding function, called operator<<(), returns a reference to ostream
Overloading Output • It accepts two arguments: a reference to ostream (locally named out in this example) and an integer (locally named n in this example) • C++ overloads the << operator to work with the built-in data types; you also may overload the << operator to work with your own classes • To overload << operator so it can work with a Sale object, you must add the overloaded operator <<() function to the Sale class
Overloading Output • The operator <<() function is a friend to the class of the object it wants to print out, e.g. Sale here.
Overloading Output Ex7-5.cpp • Overload the insertion operator to work with the SalesOffice class you created earlier in this chapter
Overloading Input • If the << operator can be overloaded for output, it makes sense that the >> operator also can be overloaded for input • The advantage of overloading operators such as >> is that the resulting programs look cleaner and are easier to read • You can create an extraction operator, or operator>>() function, that uses istream (which is defined in iostream.h, along with ostream) by using a prototype as follows: friend istream& operator>>(istream &in, Sale &Sale);
Overloading Input • You could improve the operator>>() function shown in Figure 8-13 by adding code that verifies valid receipt numbers and sale amounts • Add an overloaded operator>>() function for the SalesOffice class Ex7-6.cpp
Overloading ++ and -- • With C++, you use ++ to increment variables, and -- to decrement variables • When a prefix operator such as ++ is used in an expression, the mathematical operation takes place before the expression is evaluated • When the postfix operator is used, the expression is evaluated before the mathematical operation takes place • Within the operator ++() function in the Inventory class, you can write the statement that increases numSold in several different ways
Overloading ++ and -- • The statements numSold++;, numSold = numSold +1;, and numSold += 1; all would work
Using Postfix Increment and Decrement Operators • A problem arises if you want to use a postfix ++ operator as well as a prefix ++ operator with a class • When you overload any C++ function, you must supply different argument lists; for the postfix ++ operator, you use an integer argument • The Inventory class postfix operator ++() function prototype is: Inventory& operator++(int); Ex7-8.cpp
Overloading the == Operator • Writing an operator ==() function should be an easy task • You simply decide what will constitute equality in class members • When you create your own classes, you choose whether equivalency means that every data field must be equivalent, or only specific data members • The operator ==() function may return either an integer or a boolean variable representing true or false
Overloading the == Operator • A variable of type bool can hold one of two values: true or false • Some older C++ compilers do not support the bool type; with those compilers you would use the first version of operator = =() that returns an integer
Overloading the = Operator EX7-9.cpp • The = operator can be overloaded for use with your own classes • Unlike other operators, if you don’t define the = operator, C++ provides a definition for you • If you want the = operator to do something other than assign each member, then you must create a customer operator=()function • In addition, if the class contains data fields that are pointers, you should create a custom function
Overloading [ ] and ( ) • The subscript operator, operator[ ], is declared like any other function, but called in a manner similar to accessing an array element • You can include any instructions you want within an operator [ ] function • Typically, you use this function to perform a task that both requires an argument and does not quite fit into another operator’s usual meaning • Consider a Book class such as the one shown in Figure 8-25
Overloading [ ] and ( ) Ex7-10.cpp
Using the Parentheses Operator • You can use the parentheses operator to make multiple assignments within a class • To overload the parentheses operator to assign both an author and a price to a member of the Book class, you can create the function
References • Reference defined: • Name of a storage location • Similar to "pointer" • Example of stand alone reference: • int robert;int& bob = robert; • bob is reference to storage location for robert • Changes made to bob will affect robert • Confusing?
References Usage • Seemingly dangerous • Useful in several cases: • Call-by-reference • Often used to implement this mechanism • Returning a reference • Allows operator overload implementations tobe written more naturally • Think of as returning an "alias" to a variable
Returning Reference • Syntax:double& sampleFunction(double& variable); • double& and double are different • Must match in function declaration and heading • Returned item must "have" a reference • Like a variable of that type • Cannot be expression like "x+5" • Has no place in memory to "refer to" Ex7-8.cpp: cout<< anItem+secItem;
Returning Reference in Definition • Example function definition:double& sampleFunction(double& variable){ return variable;} • Trivial, useless example • Shows concept only • Major use: • Certain overloaded operators
More exampleson overloaded operators • Ex7-11.cpp • Ex7-12.cpp • Ex7-13.cpp • Ex7-14.cpp
Summary • The built-in + operator is polymorphic in C++; it can take one or two arguments and have a different meaning in each case • Operator overloading is the process by which you apply operators to your own abstract data types • The name of the operator function that overloads the + symbol is operator+() • The syntax involved in using the + operator alone is simpler, more natural, and easier to remember than using an ordinary member function
Summary • You can overload the + operator to add two class objects, or a class object and a primitive object • To enable you to chain mathematical operations, you overload the operator functions to return a class object • The << operator is overloaded by C++; it is both a bitwise left-shift operator and an output operator • The >> operator can be overloaded for input • When you overload the prefix and postfix ++ and - - operators to work with your classes, the same prefix/postfix rules apply as they do with simple built-in types