(Latest Revision: 10/06/2000)
ch08_Notes04_Overloads
ch08 Notes on Overloads
Polymorphism: the meaning of a function or operator can vary
according to the number of or data types of the parameters or the
class (data type) of the invoking object.
Simple example(s):
- "5 + 4" and "5.0 + 4.0" really operate quite
differently. The operator takes a different form
depending on the data types of the operands. If s and
t are strings, s+t may mean the result of appending t
to s.
If you define a new class, operators like "==" won't be supplied
by the compiler. A "shallow" form of the operator "="
will be furnished, but you may have to redefine "=" to get
it to do what it is supposed to do.
For example, to provide a definition for "==" that works for your
new list class, you can put code like this inside the class
definition in the header file for the class (e.g. listClass.h):
virtual bool operator==(const listClass & Rhs) const ;
The items in boldface are keywords.
Inside the implementation file (say listClass.cpp) you put code
like this:
bool listClass::operator==(const listClass& Rhs) const
{
bool IsEqual;
if (Size != Rhs.Size)
IsEqual = false; // lists have unequal lengths
else if ( (Head == NULL) && (Rhs.Head == NULL) )
IsEqual = true; // both lists are empty
else // lists have same length > 0;
// head pointers not NULL
{ // compare items
ptrType LeftPtr = Head;
ptrType RightPtr = Rhs.Head;
for (int Count = 1;
(Count <= Size) &&
(LeftPtr->Item == RightPtr->Item);
++Count)
{ LeftPtr = LeftPtr->Next;
RightPtr = RightPtr->Next;
} // end for
IsEqual = Count > Size;
} // end if
return IsEqual;
} // end operator==
Assuming that "==" 'makes sense' for comparing list items, the
code above states in essence that two lists are equal if they
have the same length and their corresponding elements are equal.
After putting the definitions illustrated above in place, we may
make comparisions like "X==Y" where X and Y are objects of the
list class. When we write such code, the compiler interprets it
as a call to the operator== defined as we showed. Y plays the
role of the Rhs parameter (right hand side of the operator). X
plays the role of the object that receives the message.
The programmer may overload these operators too: { <, <=, >, >= }.
Also it is typically necessary to overload "=" when a class
contains a pointer to a dynamically allocated structure. We do
this to get a "deep copy" instead of a "shallow copy."
There are some subtleties:
- To get things like L = M = N to work right, you need
to make "=" return a reference to the invoking
object.
- You need to avoid a "memory leak" in the
implementation of "=". In particular when some
dynamically allocated structure is about to be
replaced, the code must first deallocate the old
structure.
- You have to write the code so that a call like L = L
will not do the wrong thing.
GUIDELINES:
- You can overload any C++ operator except { ., .*, ::,
?:, sizeof)
- You cannot define new operators by overloading symbols
that are not already operators in C++.
- You cannot change the standard precedence of a C++
operator or the number of its operands.
- At least one operand of an overloaded operator must be
an instance of a class.
- A typical class should overload at least the
assignment (=), the equality (== and !=), and the
relational (<, <=, >, >=) operators.