1 / 47

Operator Functions and Class Use: Redefining C++'s Operators

Learn how to redefine C++'s operators for class use, including operator(), operator[], and data type conversions. Explore class inheritance, polymorphism, and common programming errors related to operator functions.

rbrennan
Download Presentation

Operator Functions and Class Use: Redefining C++'s Operators

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Objectives You should be able to describe: • Operator Functions • Two Useful Alternatives – operator() and operator[] • Data Type Conversions • Class Inheritance and Polymorphism • Common Programming Errors

  2. Operator Functions • C++ operators listed in Table 14.1 can be redefined for class use, subject to certain restrictions • Symbols not in Table 14.1 cannot be redefined • ., ::, and ?: symbols cannot be redefined • New operator symbols cannot be created • Neither the precedence nor the associativity of C++’s operators can be modified

  3. Operator Functions (continued) • Additional restrictions on redefining C++ operators for class use • Operators cannot be redefined for built-in types • Unary operator cannot be changed to binary operator, and vice versa • Operator must be member of a class or be defined to take at least one class member as an operand

  4. Operator Functions (continued)

  5. Operator Functions (continued)

  6. Operator Functions (continued) • Providing class with operators requires determination of: • Operations that make sense for class • How operations should be defined • Example (Date class of Chapter 12): Define a small meaningful set of operators • Addition of two dates not meaningful • Addition of an integer to a date or subtraction of an integer from a date is meaningful • Integer defined as number of days to/from a date

  7. Operator Functions (continued) • Defining more Date class operators • Subtraction of 2 dates is meaningful • Number of days between two dates • Comparison of two dates is meaningful • Does one date occur before another? • User-defined function: Function that redefines C++’s built-in operator symbols for class use

  8. Operator Functions (continued) • Declaring and implementing operator functions: Same as for all C++ member functions except: • Function’s name connects appropriate operator symbol to operator defined by the function • Format: operator <symbol> where symbolis an operator listed in Table 14.1 • Examples: operator++ is the name of addition function operator== is the name of comparison function

  9. Operator Functions (continued) • Writing operator function: Function accepts desired inputs and produces correct return value • Creating comparison function for Date class: Compare two dates for equality • Select C++’s equality operator • Function name is operator== • Accepts two Date objects • Compares objects • Returns a boolean value indicating result • True for equality, False for inequality

  10. Operator Functions (continued) • Prototype of comparison function bool operator==(const Date&); • Indicates that function is named operator== • Function returns integer • Accepts a reference to Date object • Second Date object calls the function

  11. Operator Functions (continued) • Writing comparison function: bool Date::operator==(const Date& date2) { if( day == date2.day && month == date2.month && year == date2.year) return true; else return false; } • const keyword ensures that the dereferenced Date object cannot be changed in the function

  12. Operator Functions (continued) • Calling operator function: Same syntax as calling C++ built-in types • Example: If a and b are objects of type Date, the expression if (a == b) is valid • if (a.operator ==b) is also valid • Program 14.1 is complete program including: • Declaration and definition of operator function • if statement with comparison operator function

  13. Operator Functions (continued)

  14. Operator Functions (continued)

  15. Operator Functions (continued) • Creating an addition function for Date class • Select C++’s addition operator • Function name is operator+ • Accepts Date object and an integer object • Adds integer to Date to return a Date • Suitable prototype: Date operator+(int) • Data conversion for Date class required • Resulting day returned must be in range 1 – 30 • Resulting month returned must be in range 1 – 12

  16. Operator Functions (continued) • Suitable addition function implementation Date Date::operator+(int days) { Date temp; // a temporary Date to store the result temp.day = day + days; // add the days temp.month = month; temp.year = year; while (temp.day > 30) // now adjust the months { temp.month++; temp.day -= 30; } while (temp.month > 12) // adjust the years { temp.year++; temp.month -= 12; } return temp; // the values in temp are returned }

  17. Operator Functions as Friends • Functions in Programs 14.1 and 14.2 constructed as class members • All operator functions (except for =, (), [], ->) may be written as friend functions • Example: operator+() function from Program 14.2 • If written as friend, suitable prototype would be friend Date operator+ (Date&, int); • Friend version contains reference to Date object that is not contained in member version • Table 14.2: shows equivalence of functions and arguments required

  18. Operator Functions as Friends (continued)

  19. Operator Functions as Friends (continued) • Program 14.2’s operator+() function, written as a friend Date operator+(Date& op1, int days) { Date temp; // a temporary Date to store the result temp.day = op1.day + days; // add the days temp.month = op1.month; temp.year = op1.year; while (temp.day > 30) // now adjust the months { temp.month++; temp.day -= 30; } while (temp.month > 12) // adjust the years { temp.year++; temp.month -= 12; } return temp; // the values in temp are returned }

  20. Operator Functions as Friends (continued) • Difference between the member and friend versions of operator+()function: Explicit use of additional Date parameter (op1) • Convention for choosing between friend or member implementation: • Member function: Better for binary functions that modify neither operand (such as ==, +, -) • Friend function: Better for binary functions that modify one of their operands

  21. The Assignment Operator Revisited • Drawback of simple assignment operator function (from Section 13.1): It returns no value • Multiple assignments (a = b = c) not possible • Can use operator function that has return type together with this pointer • Prototype and implementation of modified function illustrated on next slide • Function in Program 14.3 allows multiple assignment

  22. The Assignment Operator Revisited (continued) • Prototype for modified assignment operator Date operator=(const Date&); • Implementation of prototype Date Date::operator=(const Date &newdate) { day = newdate.day; // assign the day month = newdate.month; // assign the month year = newdate.year; // assign the year return *this; }

  23. Two Useful Alternatives – operator() and operator[ ] • Sometimes operations are needed that have more than two arguments • Limit of two arguments on binary operator functions • Example:Date objects contain three integer data members: month, day, and year • Might want to add an integer to any of these three members (instead of just the day member as done in Program 14.2)

  24. Two Useful Alternatives – operator() and operator[ ] (continued) • operator() (parentheses operator): No limit on number of arguments that can be passed to it • Addresses problem of passing three integers to Date addition operator function • operator[ ] (subscript operator): Used where single non-object argument is required • Parentheses and subscript operators must be defined as member (not friend) functions

  25. Data Type Conversions • Conversion from one built-in data type to another discussed in Chapter 3 • Introduction of user-defined data types expands possibilities to following cases • Conversion from built-in type to built-in type • Conversion from built-in type to class (user-defined) type • Conversion from class (user-defined) type to built-in type • Conversion from class (user-defined) type to class (user-defined) type

  26. Data Type Conversions (continued) • Conversion from built-in to built-in: • Implicit conversion: Occurs in context of a C++ operation • Example: When double precision number is assigned to integer variable, only integer portion stored • Explicit conversion: Occurs when cast is used • Format dataType (expression)

  27. Data Type Conversions (continued) • Conversion from built-in to class: Done using constructor functions • Type conversion constructor: Constructor whose first argument is not member of its class and whose remaining arguments, if any, have default values • If the first argument is built-in data type, the constructor can be used to cast built-in data type to class object • Program 14.5 demonstrates this conversion type

  28. Data Type Conversions (continued) • Conversion from class to built-in: Done by using: • Conversion operator function: Member operator function that has name of built-in data type or class • When operator function has built-in data type name, it is used to convert from class to built-in data type • Usage of this type of function demonstrated in Program 14.6

  29. Data Type Conversions (continued) • Conversion from class to class: Done using member conversion operator function • Same as cast from user-defined to built-in data type • In this case, operator function uses class name being converted to rather than built-in data name • Demonstrated in Program 14.7

  30. Class Inheritance and Polymorphism • Ability to create new classes from existing ones is underlying motivation behind class and object-oriented programming techniques • These techniques facilitate reusing existing code in new ways without need for retesting and validation • Permits class designers to make a class available to others for additions and extensions without relinquishing control over existing features

  31. Inheritance • Deriving one class from another class • Base class (parent class, or superclass): Initial class used as basis for derived class • Derived class (child class, or subclass): A completely new class that incorporates all of the data and member functions of its base class • Usually adds new data and function members • Can override any base class function

  32. Inheritance (continued) • Inheritance example: Three geometric shapes - circle, cylinder, and sphere • Shapes share common characteristic: radius • Can make circle base type for the other two shapes (Figure 14.1) • By convention, arrows always point from derived class to base class • Reformulating these shapes as class types we would make circle base class and derive cylinder and sphere classes from it

  33. Inheritance (continued)

  34. Access Specifications • Until now we have used only private and public access specifiers within class • private status ensures that data members can be accessed only by class member functions or friends • Prevents access by any nonclass functions (except friends) • Also precludes access by any derived class functions

  35. Access Specifications (continued) • protected access: Third access specification permits only member or friend function access • Permits this restriction to be inherited by any derived class • Derived class defines its inheritance subject to base class’s access restrictions • Class-access specifier: Listed after colon at start of its declaration section, defines inheritance • Table 14.3 lists inherited access restrictions

  36. Access Specifications (continued)

  37. Access Specifications (continued) • Example: Derive Cylinder class from Circle class // BASE class declaration class Circle { protected: double radius; public: Circle(double = 1.0); // constructor double calcval(); }; // class implementation // constructor Circle::Circle(double r) // constructor { radius = r; } // calculate the area of a circle double Circle::calcval() { return(PI * radius * radius); }

  38. Access Specifications (continued) • Example: Derived Cylinder class // class declaration where // Cylinder is derived from Circle class Cylinder : public Circle { protected: double length; // add one additional data member and public: // two additional function members Cylinder(double r = 1.0, double l = 1.0) : Circle(r), length(l) {} double calcval(); }; // class implementation double Cylinder::calcval() // this calculates a volume { return (length * Circle::calcval()); // note the base // function call }

  39. Polymorphism • Permits same function name to invoke one response in objects of base class and another response in objects of derived class • Example of polymorphism: Overriding of base member function using an overloaded derived member function, as illustrated by the calcval() function in Program 14.8 • Function binding: Determines whether base class or derived class version of function will be used

  40. Polymorphism (continued) • Static binding: Determination of which function to be called is made at compile time • Used in normal function calls • Dynamic binding: Determination of which function to be called is made at run time (via virtual function) • Virtual function (Example in Program 14.10): Creates pointer to function to be used • Value of pointer variable is not established until function is actually called • At run time, and on the basis of the object making the call, the appropriate function address is used

  41. Common Programming Errors • Attempting to redefine an operator’s meaning as it applies to C++’s built-in data types • Redefining an overloaded operator to perform a function not indicated by its conventional meaning • Will work but is bad programming practice • Attempting to make conversion operator function a friend, rather than a member function

  42. Common Programming Errors (continued) • Attempting to specify return type for member conversion operator function • Attempting to override virtual function without using same type and number of parameters as original function • Using the keyword virtual in class implementation section • Functions are declared as virtual only in class declaration section

  43. A First Book of C++: From Here To There, Third Edition Summary • User-defined operators can be constructed for classes by using member operator functions • User-defined operators may be called as a conventional function with arguments or as an operator expression • Subscript operator function, operator[], permits a maximum of one nonclass argument • Parentheses operator function, operator(), has no limits on number of arguments

  44. Summary (continued) • Four categories of data type conversions: • Built-in types to built-in types • Built-in types to class (user-defined) types • Class (user-defined) types to built-in types • Class types to class (user-defined) types • Type conversion constructor: Constructor whose first argument is not a member of its class and whose remaining arguments, have default values

  45. Summary (continued) • Conversion operator functionis member operator function that has the name of built-in data type or class • Inheritanceis capability of deriving one class from another class • Base class functions can be overridden by derived class functions with the same name

  46. Summary (continued) • Polymorphism: Having same function name invoke different responses on basis of the object making function call • Static binding: Determination of which function is invoked is made at compile time • Dynamic binding: Determination made at run time • Virtual functionspecification designates that dynamic binding should take place

More Related