Module 4:
Operator Overloading
Prof. Tran Minh Triet
1
Acknowledgement
vSlides
§ Course CS202: Programming Systems
Instructor: MSc. Karla Fant,
Portland State University
§ Course CS202: Programming Systems
Instructor: Dr. Dinh Ba Tien,
University of Science, VNU-HCMC
§ Course DEV275: Essentials of Visual Modeling with
UML 2.0
IBM Software Group
2
Outline
vWhat is function overloading?
vOperator overloading in C++
vOverloading cin and cout
Overloading
vThere are many different “definitions” for
the same name
vIn C++, overloading functions are
differentiated by their signatures (i.e.
number/types of arguments)
v Note: the return type is not considered in
differentiating overloading functions.
Operators
n We can do the following for built-in types
void main()
{
int a, b;
int c = a + b;
}
n We define classes, we also want to do the
same for two objects, like below
void main()
{
MyString str1, str2;
MyString str3 = str1 + str2;
}
Operator Overloading
vTo define operator implementations for our
new user-defined types
vFor example, operators such as +, -, *, / are
already defined for built-in types
vWhen we have a new data type, e.g.
CFraction, we need to define new operator
implementations to work with it.
Operators can be overloaded in C++
+ - * / % ^ &
| ~ ! = < > +=
-= *= /= %= ^= &= |=
<< >> >>= <<= == != <=
>= && || ++ -- ->* ,
-> [] () new new[] delete delete[]
• Operator :: or . or .* cannot be defined by users.
• Operators sizeof, typeid, ?: cannot be overloaded.
• Operators =, ->, [], () can only be overloaded by non-static functions
Overloading guidelines
vDo what users expect for that operator.
vDefine them if they make logical sense. E.g.
subtraction of dates are ok but not
multiplication or division
vProvide a complete set of properly related
operators: a = a + b and a+= b have the same
effect
Syntax
vDeclared & defined like other methods,
except that the keyword operator is used.
<returned-type> operator <op>(<arguments>)
Example:
bool CFullName::operator==(const CFullName& rhs)
{
return ((m_sFirstName==rhs.m_sFirstFName) &&
(m_sSurname==rhs.m_sSurName));
}
Operators in use
int main()
{
CFullName s1, s2;
if (s1 == s2) //s1.operator==(s2)
{
...
}
...
}
Notes about Op overloading
vSubscript operators often come in pair
const A& operator[] (int index) const;
A& operator[] (int index);
vMaintain the usual identities for x == y and
x != y
vPrefix/Postfix operators for ++ and --
§ Prefix returns a reference
§ Postfix return a copy
Two types of operator
qIndependent operator
Fraction operator +( Fraction p1, Fraction p2 );
qDoes not belong to any class
qNumber of arguments = operator n-nary.
qClass operator
Fraction Fraction::operator +( Fraction p );
qA method of class
qNumber of arguments = operator n-nary - 1
q They act the same!!
Member and non-member functions
int main()
{
CFullName s1, s2;
if (s1 == s2)
// member: s1.operator==(s2)
// or non-member: operator==(s1, s2)
{
...
}
...
}
Limitations for operators
n We cannot create a new operator (we redefine
instead)
n We cannot redefine operators for build-in types
n We cannot change operator n-nary
n We cannot change operator precedence order
v Operator :: or . or .* cannot be defined by users.
v Operators sizeof, typeid, ?: cannot be overloaded.
v Operators =, ->, [], () can only be overloaded by non-
static functions
Overloading Guidelines
vDo what users expect for that operator.
vDefine them if they make logical sense. E.g.
subtraction of dates are ok but not
multiplication or division
vProvide a complete set of properly related
operators: a = a + b and a+= b have the same
effect
Example
v class Array
v {
v int* elements;
v int length;
v int operator[](const int index)
v {
v if (index >= 0 && index < length)
v return this->elements[index];
v else
v throw (index);
v }
v };
Practice
n Fraction operator+ (const Fraction &ps)
n Fraction operator+ (const int x)
Example
v class Fraction
v {
v int numerator;
v int denominator;
v bool operator==(const Fraction &ps)
v {
v int result = this->numerator * ps.denominator - this->denominator *
ps.numerator;
v if (result == 0)
v return true;
v else
v return false;
v }
v };
Special operators
n Assignments (=, +=, -=, *=, /=, …):
nProvide operator += for Fraction.
nn-nary?
nReturn result?
Fraction& Fraction::operator +=( const Fraction &p );
n Practice:
nFraction& operator=(const Fraction &ps)
nFraction& operator+=(const Fraction &ps)
nFraction& operator+=(const int x)
Example
v class Fraction
v {
v int *numerator;
v int *denominator;
v Fraction& operator=(const Fraction &ps) //Toán tử gán bằng
v {
v if (this == &ps) //Tránh a = a
v return *this;
v delete numerator; //Xóa vùng nhớ cũ
v delete denominator;
v numerator = new int;// Tạo lại vùng nhớ mới
v denominator = new int;
v *this->numerator = *ps.numerator;//Gán giá trị cho vùng nhớ mới
v *this->denominator = *ps.denominator;
v return *this;
v }
Special operators
n Increasing / Decreasing (++, --):
nProvide operator ++ for Fraction
nn-nary?
nReturn result?
nPrefix vs. posfix?
n Practice:
n Fraction& Fraction::operator ++( ); // Prefix.
n Fraction Fraction::operator ++( int x ); // Posfix, fake
argument.
Example
v //Toán tử tie) n to+ ++a
v Fraction& operator++()
v {
v //Do việ c xử lý xong mới gán, nên chı̉ ca) n xử lý và trả ve) chính nó
v this->numerator = this->numerator + this->denominator;
v return *this;
v }
v //Toán tử hậ u to+ a++
v Fraction operator++(int x)
v {
v //Gọ i phương thức sao chép, chép giá trị trước
v Fraction result(*this);
v //Tie+ n hành xử lý trực tie+ p trên đo+ i tượng hiệ n tạ i
v this->numerator = this->numerator + this->denominator;
v //Trả ve) đo+ i tượng sao chép, không thực hiệ n xử lý
v return result;
v }
Friend function
n Operator +
nProvide operator + for Fraction
nUse independent operator
Fraction operator + ( const Fraction &p1, const Fraction &p2);
nHow to access private members?
n Operator <<
nProvide operator << for Fraction
Fraction p( 1, 3 );
cout << p;
nWhich class operator << belongs to?
The keyword: friend
vWith the keyword friend, you grant access to
other functions or classes
vFriend functions give a flexibility to the class.
It doesn’t violate the encapsulation of the
class.
vFriendship is “directional”. It means if class A
considers class B as its friend, it doesn’t mean
that class B considers A as a friend.
Example
class CDate
{
public:
...
friend void doSomething();
private:
int m_iDay, m_iMonth, m_iYear;
}
vIn doSomething(), we can have access to
private data members of the class CDate
Friend functions
vFriend functions is called like f(x) while
member functions is called x.f()
vUse member functions if you can. Only choose
friend functions when you have to.
vSometimes, friend functions are good:
§ Binary infix arithmetic operators, e.g. +, -
§ Cannot modify original class, e.g. ostream
Friend functions
class CSample
{
private:
int m_a, m_b;
public:
friend int Compute(CSample x);
}
Friend functions
int Compute(CSample x)
{
return x.m_a+x.m_b;
}
main()
{
CSample x;
…
cout << "The result is:“ << Compute (x);
}
Overloading cin and cout
vWe do not have access to the istream or
ostream code à cannot overload << or >> as
member functions
vThey cannot be members of the user-defined
class because the first parameter must be an
object of that type
vOperators << and >> must be non-members, but
it needs to access to private data members à
make them friend functions
Typical syntax
vThe general syntax for insertion and
extraction operator overloadings:
ostream& operator<<(ostream& out, const CFraction& x)
{
out << x.numerator << “ / “ << x.denominator;
return out;
}
istream& operator>>(istream& in, CFraction& x);
Exercises
vImplement insertion and extraction operators
for CFraction and CDate class
Practice
n Let’s define and implement a Fraction class
which represents a fraction number with the
following operators
nArithmetic: +, *
nComparison: >, <, ==, >=, <=, !=
nAssignment: =, +=, *=
nIncreasing / Decreasing: ++, -- (add/subtract 1 unit)
nType-cast: (float), (int)
nInput/Output: >>, <<
Practice
vDefine and implement a Vector class with
necessary operators
§ Dot product: 𝐴. 𝐵 = 𝐴 𝐵 cos 𝜃
§ Hadamard product: 𝐴. 𝐵 ! = 𝐴! 𝐵!
Practice
v Define and implement a Matrix class with
necessary operators
§ Matrix product: 𝐴 𝑚×𝑛 . 𝐵 𝑛×𝑝 = 𝐶 𝑚×𝑝
§ Hadamard product: 𝐴. 𝐵 !" = 𝐴!" 𝐵!"
§ Remark:
• int operator[](const int i, const int j)
• int operator()(const int i, const int j)