www.gibmonks.com

Main Page




Previous Page
Next Page

[Page 621 (continued)]

Summary

  • C++ enables the programmer to overload most operators to be sensitive to the context in which they are usedthe compiler generates the appropriate code based on the context (in particular, the types of the operands).

  • Many of C++'s operators can be overloaded to work with user-defined types.

  • One example of an overloaded operator built into C++ is operator <<, which is used both as the stream insertion operator and as the bitwise left-shift operator. Similarly, >> is also overloaded; it is used both as the stream extraction operator and as the bitwise right-shift operator. Both of these operators are overloaded in the C++ Standard Library.

  • The C++ language itself overloads + and -. These operators perform differently, depending on their context in integer arithmetic, floating-point arithmetic and pointer arithmetic.

  • The jobs performed by overloaded operators can also be performed by function calls, but operator notation is often clearer and more familiar to programmers.

  • An operator is overloaded by writing a non-static member-function definition or global function definition in which the function name is the keyword operator followed by the symbol for the operator being overloaded.

  • When operators are overloaded as member functions, they must be non-static, because they must be called on an object of the class and operate on that object.

  • To use an operator on class objects, that operator must be overloadedwith three exceptions: the assignment operator (=), the address operator (&) and the comma operator (,).


  • [Page 622]
  • You cannot change the precedence and associativity of an operator by overloading.

  • You cannot change the "arity" of an operator (i.e., the number of operands an operator takes).

  • You cannot create new operators; only existing operators can be overloaded.

  • You cannot change the meaning of how an operator works on objects of fundamental types.

  • Overloading an assignment operator and an addition operator for a class does not imply that the += operator is also overloaded. Such behavior can be achieved only by explicitly overloading operator += for that class.

  • Operator functions can be member functions or global functions; global functions are often made friends for performance reasons. Member functions use the this pointer implicitly to obtain one of their class object arguments (the left operand for binary operators). Arguments for both operands of a binary operator must be explicitly listed in a global function call.

  • When overloading (), [], -> or any of the assignment operators, the operator overloading function must be declared as a class member. For the other operators, the operator overloading functions can be class members or global functions.

  • When an operator function is implemented as a member function, the leftmost (or only) operand must be an object (or a reference to an object) of the operator's class.

  • If the left operand must be an object of a different class or a fundamental type, this operator function must be implemented as a global function.

  • A global operator function can be made a friend of a class if that function must access private or protected members of that class directly.

  • The overloaded stream insertion operator (<<) is used in an expression in which the left operand has type ostream &. For this reason, it must be overloaded as a global function. To be a member function, operator << would have to be a member of the ostream class, but this is not possible, since we are not allowed to modify C++ Standard Library classes. Similarly, the overloaded stream extraction operator (>>) must be a global function.

  • Another reason to choose a global function to overload an operator is to enable the operator to be commutative.

  • When used with cin and strings, setw restricts the number of characters read to the number of characters specified by its argument.

  • istream member function ignore discards the specified number of characters in the input stream (one character by default).

  • Overloaded input and output operators are declared as friends if they need to access non-public class members directly for performance reasons.

  • A unary operator for a class can be overloaded as a non-static member function with no arguments or as a global function with one argument; that argument must be either an object of the class or a reference to an object of the class.

  • Member functions that implement overloaded operators must be non-static so that they can access the non-static data in each object of the class.

  • A binary operator can be overloaded as a non-static member function with one argument or as a global function with two arguments (one of those arguments must be either a class object or a reference to a class object).

  • A copy constructor initializes a new object of a class by copying the members of an existing object of that class. When objects of a class contain dynamically allocated memory, the class should provide a copy constructor to ensure that each copy of an object has its own separate copy of the dynamically allocated memory. Typically, such a class would also provide a destructor and an overloaded assignment operator.


  • [Page 623]
  • The implementation of member function operator= should test for self-assignment, in which an object is being assigned to itself.

  • The compiler calls the const version of operator[] when the subscript operator is used on a const object and calls the non-const version of the operator when it is used on a non-const object.

  • The array subscript operator ([]) is not restricted for use with arrays. It can be used to select elements from other types of container classes. Also, with overloading, the index values no longer need to be integers; characters or strings could be used, for example.

  • The compiler cannot know in advance how to convert among user-defined types, and between user-defined types and fundamental types, so the programmer must specify how to do this. Such conversions can be performed with conversion constructorssingle-argument constructors that turn objects of other types (including fundamental types) into objects of a particular class.

  • A conversion operator (also called a cast operator) can be used to convert an object of one class into an object of another class or into an object of a fundamental type. Such a conversion operator must be a non-static member function. Overloaded cast-operator functions can be defined for converting objects of user-defined types into fundamental types or into objects of other user-defined types.

  • An overloaded cast operator function does not specify a return typethe return type is the type to which the object is being converted.

  • One of the nice features of cast operators and conversion constructors is that, when necessary, the compiler can call these functions implicitly to create temporary objects.

  • Any single-argument constructor can be thought of as a conversion constructor.

  • Overloading the function call operator () is powerful, because functions can take arbitrarily long and complex parameter lists.

  • The prefix and postfix increment and decrement operator can all be overloaded.

  • To overload the increment operator to allow both preincrement and postincrement usage, each overloaded operator function must have a distinct signature, so that the compiler will be able to determine which version of ++ is intended. The prefix versions are overloaded exactly as any other prefix unary operator would be. Providing a unique signature to the postfix increment operator is accomplished by providing a second argument, which must be of type int. This argument is not supplied in the client code. It is used implicitly by the compiler to distinguish between the prefix and postfix versions of the increment operator.

  • Standard class string is defined in header <string> and belongs to namespace std.

  • Class string provides many overloaded operators, including equality, relational, assignment, addition assignment (for concatenation) and subscript operators.

  • Class string provides member function empty, which returns true if the string is empty; otherwise, it returns false.

  • Standard class string member function substr obtains a substring of a length specified by the second argument, starting at the position specified by the first argument. When the second argument is not specified, substr returns the remainder of the string on which it is called.

  • Class string's overloaded [] operator does not perform any bounds checking. Therefore, the programmer must ensure that operations using standard class string's overloaded [] operator do not accidentally manipulate elements outside the bounds of the string.

  • Standard class string provides bounds checking with member function at, which "throws an exception" if its argument is an invalid subscript. By default, this causes a C++ program to terminate. If the subscript is valid, function at returns the character at the specified location as an lvalue or an rvalue, depending on the context in which the call appears.


  • [Page 624]
  • C++ provides the keyword explict to suppress implicit conversions via conversion constructors when such conversions should not be allowed. A constructor that is declared explicit cannot be used in an implicit conversion.


Previous Page
Next Page