210 likes | 687 Views
CS 222 Object Oriented Programming Using C++. Operator Overloading. Contents. What is Operator Overloading How to Overload Restrictions on Operator Overloading Unary and binary Operator Overloading Overloading Inserters and Extractors. What is Operator Overloading.
E N D
CS 222 Object Oriented Programming Using C++ Operator Overloading
Contents • What is Operator Overloading • How to Overload • Restrictions on Operator Overloading • Unary and binary Operator Overloading • Overloading Insertersand Extractors
What is Operator Overloading • Using operators with objects • Operator overloaded to define a new meaning for an operator for a certain class • Example myArray class can overload + to mean add a new element • Enables creating new data types (complex numbers, string, point, date…etc) • Overloading provides concise notation • object2 = object1.add(object2); • object2 = object2 + object1;
How to Overload • Overloading operators • Create a function for the class • Name function operator followed by symbol • Operator+ for the addition operator + • General form of an operator function • typeclassname::operator#(arg-list) { operations relative to the class } Where # is the operator to be overloaded • Operator functions can be either members or non-members of a class. Non-member functions are often friend functions of a class
How to Overload • Using operators on a class object • It must be overloaded for that class • Exceptions: • Assignment operator, = • Memberwise assignment between objects • Address operator, & • Returns address of object • However both can be overloaded • We will overload the assignment operator for classes that contain pointer members because of the dangerous side effects of memberwise assignment
Restrictions on Operator Overloading • Cannot change • How operators act on built-in data types • I.e., cannot change integer addition • Precedence of operator (order of evaluation) • Use parentheses to force order-of-operations • Associativity (left-to-right or right-to-left) • Number of operands • & is unitary, only acts on one operand • Cannot create new operators • Operators must be overloaded explicitly • Overloading + does not overload +=
Binary Operator Overloading Using Member Functions Example class three_d { int x, y, z; // 3-D coordinates public: three_d() { x = y = z = 0; } three_d(int i, int j, int k) {x=i; y=j; z=k;} three_d operator+(three_d op2);//op1 is implied three_d operator=(three_d op2);// op1 is implied void show() ; }; // Overload +. three_d three_d::operator+(three_d op2) { three_d temp; temp.x=x+op2.x; // integer additions temp.y=y+op2.x; // retains is original temp.z=z+op2.z; // meaning relative to them. return temp; } // Overload assignment. three_d three_d::operator=(three_d op2) { x = op2.x; // These are integer assignments y = op2.y; // and the = retains its original z = op2.z; // meaning relative to them. return *this; } // Show X, Y, Z coordinates. void three_d::show() { cout << x << ", "; cout << y << ", "; cout << z << "\n"; } int main() { three_d a(1, 2, 3), b(10, 10, 10), c; a.show(); b.show(); c = a + b; // add a and b together c.show(); c = a + b + c; // add a, b and c together c.show(); c = b = a; // multiple assignment c.show(); b.show(); return 0; }
Binary Operator Overloading Using Member Functions • When a member function is used for overloading a binary operator the object on the left side invokes the operator function, and is passed implicitly as this. The object on the right side is passed as a parameter.
Unary Operator Overloading Using Member Functions • No object is explicitly passed to the operator function • The operation is performed on the object that generates the call to the function by using this pointer
Unary Operator Overloading Using Member FunctionsExample class three_d { int x, y, z; // 3-D coordinates public: three_d() { x = y = z = 0; } three_d(int i, int j, int k) {x = i; y = j; z = k; } three_d operator+(three_d op2);// op1 is implied three_d operator=(three_d op2);// op1 is implied three_d operator++(); // prefix version of ++ void show() ; } ; // Overload +. three_d three_d::operator+(three_d op2) { three_d temp; temp.x=x+op2.x; // These are integer additions temp.y=y+op2.y; // and the + retains is original temp.z=z+op2.z; // meaning relative to them. return temp; } // Overload assignment. three_d three_d::operator=(three_d op2) { x = op2.x; // These are integer assignments y = op2.y; // and the = retains its original z = op2.z; // meaning relative to them. return *this; } // Overload the prefix version of ++. three_d three_d::operator++() { x++; y++; z++; return *this; } // Show X, Y, Z coordinates. void three_d::show() { cout << x << ", "; cout << y << ", "; cout << z << "\n";} int main() { three_d a(1, 2, 3), b(10, 10, 10), c; a.show(); b.show(); c = a + b; // add a and b together c.show(); c = a + b + c; // add a, b and c together c.show(); c = b = a; // multiple assignment c.show(); b.show(); ++c; // increment c c.show(); return 0; }
Unary Operator Overloading Using Member Functions • In the previous example the prefix ++ operator was overloaded • ++C;
Overloading Relational and Logical Operators • Typically relational and logical operators return a true or false value such as (==,<,&&) bool three_d::operator==(three_d op2) { if ((x == op2.x) && (y == op2.y) && (z == op2.z)) return true; else return false; } three_d a,b //… if ( a == b ) cout<<“a equals b”; else cout<<“a does not equal b”; }
A Closer Look at the Assignment Operator • By default copying by assignment performs a bitwise copy of the object on the right side of the operator to the object on the left side. • This can cause problems in cases where the object allocates a memory resource. When a copy is made both objects point to the same resource. • This can be solved by overloading the assignment operator • Copying by assignment • a = b; • a = f1();
Overloading Insertersand Extractors • The predefined object cin is an instance of the istream class and it is connected to the standard input device (keyboard) • The predefined object cout is an instance of the ostream class and it is connected to the standard output device (screen) • << and >> • Already overloaded to process each built-in type • Can also process a user-defined class • Example program • Class PhoneNumber • Holds a telephone number • Print out formatted number automatically • PhoneNumber pn; • //… • cout<<pn; • (123) 456-7890
Overloading Insertersand Extractors • The predefined object cin is an instance of the istream class and it is connected to the standard input device (keyboard) • The predefined object cout is an instance of the ostream class and it is connected to the standard output device (screen) • << and >> • Already overloaded to process each built-in type • Can also process a user-defined class • Example program • Class PhoneNumber • Holds a telephone number • Print out formatted number automatically • PhoneNumber pn; • //… • cout<<pn; • (123) 456-7890
Overloading Inserters << • Inserters are stream insertion operators they insert characters into a stream • cout << x; • to overload inserters we do the following:
Overloading Insertersexample class three_d { int x, y, z; // 3-D coordinates -- now private public: three_d(int a, int b, int c) { x = a; y = b; z = c; } friend ostream &operator<<(ostream &stream, three_d obj); }; // Display X, Y, Z coordinates - three_d inserter. ostream &operator<<(ostream &stream, three_d obj) { stream << obj.x << ", "; stream << obj.y << ", "; stream << obj.z << "\n"; return stream; // return the stream } int main() { three_d a(1, 2, 3), b(3, 4, 5), c(5, 6, 7); cout << a << b << c; return 0; }
Overloading Extractors >> • Extractors are stream extraction operators they extract characters from a stream • cin >> x; • to overload extractors we do the following:
Overloading Extractorsexample class three_d { int x, y, z; // 3-D coordinates public: three_d(int a, int b, int c) { x = a; y = b; z = c; } friend ostream &operator<<(ostream &stream, three_d obj); friend istream &operator>>(istream &stream, three_d &obj); } ; // Display X, Y, Z coordinates - three_d inserter. ostream &operator<<(ostream &stream, three_d obj) { stream << obj.x << ", "; stream << obj.y << ", "; stream << obj.z << "\n"; return stream; // return the stream } // Get three dimensional values - three_d extractor. istream &operator>>(istream &stream, three_d &obj) { cout << "Enter X,Y,Z values: "; stream >> obj.x >> obj.y >> obj.z; return stream; } int main() { three_d a(1, 2, 3); cout << a; cin >> a; cout << a; return 0; }