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