Operator Overloading

It is also possible to overload the common operators of C++ to make the programs more easy to write. The same operators are overloaded to accept more types of operands. While most languages support the use of operators with different types (for example, + can be used with integer or float), C++ actually lets the user himself overload operators. The list of operators C++ will let you overload is extensive. You can look these up in your favorite C++ reference book. Virtually all of the C++ operators can be overloaded, letting you extend the language by using the same basic intuitive syntax to accomplish more things. Also, the user introduce new operators, only overloading of existing operators is allowed. Further, the following operators cannot be overloaded: a) :: the scope operator b) .* pointer to member selection operator c) .class object selector operator d) ?: the arithmetic if operator There are two major motivations for operator overloading: 1. Syntactic Sugar: sometimes it is just simpler to offer a specific operator-based syntax for some kinds of manipulations. For example, in the case of Set objects, + is conventionally known to mean "UNION", * is conventionally known to mean "INTERSECTION", etc. This is better than providing your own member functions that are not as intuitive. If you have sets A and B, it is nice to write A + B when you mean UNION, rather than A.union(B) for example. 2. Semantic Reasons: In C++, certain operators, such as assignment, are provided by default for objects. But, assignment performs memberwise-assignment, which might be wrong for some classes. For example, if a class has pointer-based data members, memberwise assignment would end up with "aliasing", where more than one object shares the same pointer value. The problem here could be that when the object is deleted, and the destructor destroys the value being pointed to, other objects could lose the value as well. So, there are fundamental reasons why C++ provides operator overloading as a feature in the langauge.

How to Overload Simple Operators

For example, you may want to extend the + operation (that usually works only for numbers) to Student objects. Of course, you have to decide what + means when applied to Student objects. So, for example, class Student { public: Student(const string &n, const string&s, int a); void display(); int get_age () const { return age; } int operator+(const Student &y); private: string name; string ssn; int age; }; Student X, Y; Normally, X + Y would be meaningless and the C++ compiler would flag it as an error. But, we can provide an operator overloading for + defined for Student as below. In this case we are providing the overloading as a non-member function: int operator+(const Student&a, const Student&b) { return a.get_age() + b.get_age(); } Example of + Overloading: Student1.cpp Note that the operator+ is NOT a member function of Student, and must go through the provided interface for Student. Anyone can provide their own operator overloading via non-members for most operators, although C++ specifies that assignment, certain conversion operators, must be overloaded as MEMBER FUNCTIONS, which is the second option. If you are the designer of Student, and you want to provide a + operator, it would be best to provide that packaged with the class as below: class Student { public: Student(const string &n, const string&s, int a); void display(); int get_age () const { return age; } int operator+(const Student &y); private: string name; string ssn; int age; }; // member function for operator+ defined int Student::operator+(const Student &y) { return age + y.age; } Example of member function overloading of + : Student.cpp

Overloading the Assignment Operator

Assignment is a specific operator that you might NEED to overload in C++. This is because memberwise assignment operator, provided by default, does not work for some objects. For example, you might end up with aliasing as we mentioned above. Also, you might get subtle problems such as memory leaks with memberwise assignment. All these problems arise when the class has non-simple (pointers, references, arrays) as data members. For these kinds of data values, the programmer should program an explicit assignment operator. class Student { public: Student(const string &n, const string&s, int a); Student(const string&s, int a); void display(); int get_age () const { return age; } private: // optional name attribute (modeled as pointer) string *name; string ssn; int age; }; Now, Student A, B; A = B; // by default would end up with A.name aliasing B.name When A is destroyed, B ends up losing its name too because it is possible that the destructor for Student gets rid of the optional name when a student is deleted. The solution is to provide a specific assignment operator as below: class Student { public: Student(const string &n, const string&s, int a); Student(const string&s, int a); void display(); int get_age () const { return age; } // assignment operator prototype Student & operator= (const Student&); private: // optional name attribute (modeled as pointer) string *name; string ssn; int age; }; Student & Student::operator= (const Student &s) { // delete the old name if it exists... if (name) delete name; if (s.name != NULL) name = new string(*(s.name)); else name = NULL; ssn = s.ssn; age = s.age; return *this; } Example of Assignment Operator : Student-Assignment.cpp

Overloading of << and >:> Operators

Finally, because of the order of operands, certain operators can only be overloaded as non-members. For example, consider operator <<. If you define this operator for Student, you can do: Student A; cout << A; That would be convenient. However, because the left operand for << is ostream, you cannot program << as a member function of ostream, which you do not control (thank God). So, the only choice is to make a non-member function that does the job as below: ostream& operator<<(ostream& os, const Student & X) { os << X.get_name() << X.get_ssn() << endl; return os; } The only question that remains at this point about operator overloading is What determines whether the operator function be a non-member or member? For one thing, if the operator has a left argument that belongs to a different class, there is no choice but to use a non-member version because the implicit left argument (namely the ``this'' pointer) will be of the wrong type. Also, some operators such as equality (``=''), subscript (``[]''), call (``()''), and member selection (``$->$'') are required to be class member functions. Other than that, the programmer is free to make choices as needed. In order to prevent the programmer from haphazardly changing the meaning of all binary operators for built in classes, it is stipulated that at least one argument for all operator overloading be a class. Also, operator precedence cannot be altered in any way. Example of << Operator Overloading: Student2.cpp
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees