You are on page 1of 11

Computational Intelligence on Automation Lab @ NCTU Learning Objectives

 Basic operator overloading


UEE1303(1070) S’12 –unary and binary operators
–as member functions
Object-Oriented
Programming in C++  Friends and automatic type conversion
–friend functions and friend classes
–constructors for automatic type conversion
Lecture 05:  References and more overloading
Understanding Friends and –input insertion << and output extraction >>
Overloading Operators –operators: ++, --, []

Hung-Pin(Charles) Wen UEE1303(1070) L05 2

Overloading for Integral Datatypes A Starting Example (1/2)

 Operators are overloaded in C/C++: class CComplex { lec5-1.cpp


– +7, 2+5, 3.25+7.3 double real, imag;
 In addition to overloading, compilers often public:
CComplex() { real=0; imag=0; }
need to perform coercion or casting when the CComplex(double r, double i) {
+ symbol is used with mixed arithmetic real=r; imag=i; }
 To use arithmetic symbols with our own CComplex cadd(CComplex & o2);
objects  must overload the symbols void display() { cout << “(” << real
–polymorphism allows the same operations << “,” << imag << “i)” << endl };
to be carried out differently };
CComplex CComplex::cadd(CComplex & o2) {
–overload the + operator with a reasonable CComplex c; c.real=real+o2.real;
meaning c.imag=imag+02.imag; return c;
–Ex: ptA + ptB //ptA∈CPoint, ptB∈CPoint }
Hung-Pin(Charles) Wen UEE1303(1070) L05 3 Hung-Pin(Charles) Wen UEE1303(1070) L05 4
A Starting Example (2/2) More Operator Overloading

int main() {  Operators +, -, %, ==, etc


CComplex c1(3,4), c2(2,-7), c3;  really just functions!
c3 = c1.cadd(c2);  Simply called with different syntax: x+7
cout << “c1 = ”; c1.display();
– + is binary operator with x and 7 as its
cout << “c2 = ”; c2.display();
cout << “c1+c2 = ”; c3.display(); operands  like this notation as humans
return 0;  Overload an operator by making it a function
lec5-1.cpp
} – +(x,7)  +: function name, x & 7:
c1 = (3,4i) arguments
c2 = (2,-7i) –function + returns sum of all its arguments
c1+c2 = (5,-3i)  If an operator is normally defined to be unary
 Using member function is cumbersome only, then you cannot overload it to be binary
– good to have c3=c1+c2 –cannot change associativity or precedence
Hung-Pin(Charles) Wen UEE1303(1070) L05 5 Hung-Pin(Charles) Wen UEE1303(1070) L05 6

Operator Overloading Perspective Overloading Basics (1/2)

 Built-in operators  Overloading operators


–e.g., +, -, =, %, ==, /, * –very similar to overloading functions
–already work for C++ built-in types –operator itself is the name of function
–in standard binary notation  Example:
 Overload these basic operators const CMoney operator+(const CMoney &obj);
–to work with our own datatypes!
–to add "Chair types", or "Money types“ –overload + for operands of type CMoney
 as appropriate for our needs –use constant reference parameters for
–in notation that we are comfortable with efficiency
–the returned value is type CMoney
 Always overload with similar actions!
 allow addition of CMoney objects
Hung-Pin(Charles) Wen UEE1303(1070) L05 7 Hung-Pin(Charles) Wen UEE1303(1070) L05 8
Overloading Basics (2/2) Review of Friends (1/2)

 Overloading operators can be classified into  Only member functions can access the
–(1) overloading member functions private data of one class
〈datatype〉 〈class_name〉::operator〈operator〉  You may want to allow a nonmember function
(〈parameter_list〉) { //functional body; } to have access to a private data
–typically, for binary operators  a friend function is a nonmember function
Ex: assignment/subscript([])/function(()) that can access the non-public members of
–(2) overloading friend functions a class
〈datatype〉 operator〈operator〉 –should be used only when absolute
(〈parameter_list〉) { //functional body; } necessary
–typically, for unary operators –avoid them simply to overcome
Ex: input insertion(<<) & output extraction(>>) encapsulation
Hung-Pin(Charles) Wen UEE1303(1070) L05 9 Hung-Pin(Charles) Wen UEE1303(1070) L05 10

Review of Friends (2/2) Example of friends (1/2)

 A nonmember function can be declared in the class CCustomer {


public or private section or first in the class friend void showAFriend(CCustomer);
int cid; double balance;
 Not required to use the word friend within in public:
the function name of a friend function CCustomer(int x=0, double y=0) {
 Overloaded functions can be friends cid=x; balance=y; }
void showCCustomer() {
–but each must be explicitly designated as a cout << cid << " with $"
friend function << balance << endl; }
–limit your use of friend functions };
void showAFriend(CCustomer c){
–necessary when you overload input and cout << c.cid << “ with $”
output operators for a class << c.balance << endl;
} lec5-2.cpp
Hung-Pin(Charles) Wen UEE1303(1070) L05 11 Hung-Pin(Charles) Wen UEE1303(1070) L05 12
Example of friends (2/2) List of Overloading Operators (1/2)

int main() {  Arithmetic


CCustomer one( 10963, 3437.95); – +, -, *, /, %
 Bitwise
//call member function – ^, &, |, ~, >>, <<
one.showCCustomer();
 Correlational
//call friend function – <, <=, >, >=, !=, ==
showAFriend(one);  Logic
– !, &&, ||
return 0;  Assignment
} lec5-2.cpp
– =, +=, -=, *=, /=, %=, <<=, >>=, &=, ^=,|=
 Other
– ++, --, [], (), ->, new, new [], delete,
delete [], ,
Hung-Pin(Charles) Wen UEE1303(1070) L05 13 Hung-Pin(Charles) Wen UEE1303(1070) L05 14

List of Overloading Operators (2/2) Overloading Operator +

 Five operators cannot be overloaded  Given previous example:


 You also cannot overload operators that you –overloaded "+" NOT member function
invent, ex: cannot redefine o1@o2
–definition is more involved than a simple
 Operators cannot be overloaded for built-in add
datatypes, ex: cannot redefine 5+3
–require issues of money-type addition
operator usual use
–must handle negative/positive values
.(dot operator) member
* pointer to member  Operator overload definitions generally
:: scope resolution very simple
?: conditional –just perform addition particular to the user-
sizeof size of defined type
Hung-Pin(Charles) Wen UEE1303(1070) L05 15 Hung-Pin(Charles) Wen UEE1303(1070) L05 16
Overloading + on CComplex Overloading + on CComplex

class CComplex { lec5-3.cpp class CComplex { lec5-3.cpp


double real, imag; double real, imag;
public: public:
CComplex() { real=0; imag=0; } CComplex() { real=0; imag=0; }
CComplex(double r, double i) { CComplex(double r, double i) {
real=r; imag=i; } real=r; imag=i; }
friend CComplex operator+( What declare
friend CComplex theoperator+(
overloading operator
CComplex& o1, Complex& o2 ); function into
CComplex& o1,a friend function
Complex& o2 );?
void display() { //... } void display() { //... }
}; };
CComplex operator+( CComplex& o1, CComplex operator+( CComplex& o1,
CComplex& o2 ){ CComplex& o2 ){
return CComplex(o1.real+o2.real, return CComplex(o1.real+o2.real,
o1.imag+o2.imag); o1.imag+o2.imag);
} }
Hung-Pin(Charles) Wen UEE1303(1070) L05 17 Hung-Pin(Charles) Wen UEE1303(1070) L05 18

Member vs. Friend Functions Overloading Operator ==

 Implement the overloading operator as a  Equality operator ==


member function –enable comparison of objects of one class
–use this to visit the data member –return bool type for true/false equality
–the left operand must be a object of same –again, it is a non-member function, like
class, Ex: c1+c2 overloading +
 What if c3=c1+x?  Overloading == on CComplex
friend bool operator==(const CComplex &,
CComplex CComplex::operator+(int& x){
return CComplex(real+x,imag); } const CComplex &);
bool operator==( const CComplex& o1,
 What if c3=x+c2?  use a friend function
const CComplex& o2 ){
CComplex operator+(int& x, CComplex& o){ return ((o1.real==o2.real)&&
return CComplex(x+o.real,o.imag); } (o1.imag==o2.imag)); }
Hung-Pin(Charles) Wen UEE1303(1070) L05 19 Hung-Pin(Charles) Wen UEE1303(1070) L05 20
Constructors Return Objects Return by non-const Value (1/2)

 Is constructor a void function?  Assume a mutator input() and non-const


–we think that way, but the truth is no overloading + in class CComplex :
–actually, it is a special function with special void CComplex::input(){
properties and can return a value! cout << "input real="; cin >> real;
cout << "input imag="; cin >> imag;
 Recall operator+ from }
CComplex CComplex::operator+(int& x){ CComplex CComplex::operator+(
return CComplex(real+x,imag); CComplex& o2 ){
} return CComplex(real+o2.real,
–return an invocation of class CComplex imag+o2.imag);
}
–So constructor actually returns an object lec5-3.cpp
named anonymous(nameless) object –return a non-const object
–allow modification of anonymous object
Hung-Pin(Charles) Wen UEE1303(1070) L05 21 Hung-Pin(Charles) Wen UEE1303(1070) L05 22

Return by non-const Value (2/2) Return by const Value

 Consider non-const in declaration:  So define the returned object as const


CComplex CComplex::operator+( const CComplex CComplex::operator+(
CComplex& o2 ){ CComplex& o2 ){
return CComplex(real+o2.real, return CComplex(real+o2.real,
imag+o2.imag); imag+o2.imag);
} }

 Given two CComplex object c1 and c2  What if ??


–object returned is a CComplex object CComplex t1(3,4), t2(2,-5), t3;
t3 = (t1 + t2); //assignment does??
–can do something with the returned object t3.input(); //legal??
–Like calling a member function  Is(t1+t2).input()a legal call??
–Ex: (t1+t2).input() Why?  t3 and (t1+t2) are different objects
Hung-Pin(Charles) Wen UEE1303(1070) L05 23 Hung-Pin(Charles) Wen UEE1303(1070) L05 24
Overloading Unary Operators Example of Unary Operators

 C++ has unary operators: int main() {


–defined as taking one operand CComplex c1(3,4), c2(2,-7), c3;
–e.g. x=-y; //set x to negated y c3 = c1 - c2; //call binary operator-
–other unary operators, ex: ++, -- cout << “c3 = ”; c3.display();
c3 = -c2; //call unary operator-
–unary operators can also be overloaded
cout << “c3 = ”; c3.display();
 Overloading operator - on CComplex return 0;
const CComplex CComplex::operator-() { } lec5-4.cpp
return CComplex(-real,-imag);
} //what if a friend func?  Output
lec5-4.cpp c3 = (1,11i)
–need no argument
c3 = (-2,7i)
–overload twice: one for binary (minus) and
one for unary (negation)
Hung-Pin(Charles) Wen UEE1303(1070) L05 25 Hung-Pin(Charles) Wen UEE1303(1070) L05 26

Overloading as Member Functions Member Operator in Action

 Previous examples: standalone functions  Example


–defined outside a class CComplex c1(3,4), c2(2,-7), c3;
c3 = c1 + c2; //call binary operator+
–use friend
–if "+" overloaded as a member operator,
 Can overload as a member operator
 variable/object cost is calling object
–implement a member function like others  object c2 is single argument
 When operator is a member function: –think of as: c3 = c1.opertor+(c2);
–only one parameter, not two! –declaration of “opertor+” in class definition
const CComplex CComplex::operator+(
–calling object serves as the first parameter
CComplex& o2) { //... }
–notice only one argument
Hung-Pin(Charles) Wen UEE1303(1070) L05 27 Hung-Pin(Charles) Wen UEE1303(1070) L05 28
Example of +/-/+= on CComplex (1/3) Example of +/-/+= on CComplex (2/3)
lec5-5.cpp
class CComplex { lec5-5.cpp //overloading as member functions
double real, imag; CComplex CComplex::operator+(CComplex& o2) {
public: CComplex t; t.real=real+o2.real;
CComplex() { real=0; imag=0; } t.imag=imag+o2.imag; return t; }
CComplex(double r, double i) { CComplex CComplex::operator+(double r) {
real=r; imag=i; } CComplex t; t.real=real+r;
void display() { cout << “(” << real t.imag=imag; return t; }
<< “,” << imag << “i)” << endl }; void CComplex::operator+=(CComplex& o2) {
CComplex operator+(CComplex& o2); real+=o2.real; imag+=o2.imag; }
CComplex operator+(double r); //overloading as friend functions
void operator+=(CComplex& o2); CComplex operator+(double r, CComplex& o1) {
friend CComplex operator+( CComplex t; t.real=r+o1.real;
double r, CComplex& o1); t.imag=o1.imag; return t; }
friend CComplex operator-(CComplex& o1); CComplex operator-(CComplex& o1) {
}; return CComplex(-o1.real,-o1.imag); }
Hung-Pin(Charles) Wen UEE1303(1070) L05 29 Hung-Pin(Charles) Wen UEE1303(1070) L05 30

Example of +/-/+= on CComplex (3/3) Overloading Operator ++/--

int main() {  ++/-- are unary operators


CComplex c1(12,-20), c2(-5, 9), c3;
–prefix operation: ++obj, --obj
c3=c1+c2; c3.display();
c3=c1+10; c3.display(); –postfix operation: obj++, obj--
c3=-8+c2; c3.display();  Declare as member functions
c2+=c1; c2.display();
c1=-c3; c1.display(); 〈CNAME〉& 〈CNAME〉::operator++(); //prefix
return 0; 〈CNAME〉 〈CNAME〉::operator++(int); //postfix
} lec5-5.cpp  Declare as friend functions
(7,-11i) //prefix friend function
(22,-20i) friend 〈CNAME〉& 〈CNAME〉::operator++(〈CNAME〉&);
(-13,9i) //postfix friend function
(7,-11i) friend 〈CNAME〉 〈CNAME〉::operator++(
(13,-9i) 〈CNAME〉&, int);
Hung-Pin(Charles) Wen UEE1303(1070) L05 31 Hung-Pin(Charles) Wen UEE1303(1070) L05 32
Example of Overloading ++ (1/2) Example of Overloading ++ (2/2)

class CCount { lec5-6.cpp //int main() lec5-6.cpp


unsigned int cnt;
CCount d1(10), d2;
public:
d2=d1++; //call postfix increment
CCount(int n=0) { cnt=n; }
d1.display();d2.display();cout << endl;
void display() { cout << cnt; }
d2=++d1; //call prefix increment
//prefix increment as member
d1.display();d2.display();cout << endl;
CCount& operator++();
++++d1;
//postfix increment as friend
d1.display();d2.display();cout << endl;
friend CCount operator++(CCount&, int);
};
11 10
CCount& CCount::operator++() {
cnt++; return *this; } 12 12
CCount operator++(CCount& x, int y) { 14 12
CCount tmp=x; x.cnt++; return tmp; }

Hung-Pin(Charles) Wen UEE1303(1070) L05 33 Hung-Pin(Charles) Wen UEE1303(1070) L05 34

Overloading >> and << Overloading >> and <<

 Enable input and output of our objects  Enable input and output of our objects
–similar to other operator overloads –similar to other operator overloads
–new subtleties –new subtleties
 Format of overloading operator >> and <<  Format of overloading operator >> and <<
istream& operator>>(istream&,〈CNAME〉&); istream&
CComplex operator>>(istream&,〈CNAME〉&);
c1(2,5), c2(-3,-2), c3;
ostream& operator<<(ostream&,〈CNAME〉&); ostream&
c3=c1+c2;operator<<(ostream&,〈CNAME〉&);
cout<<c3;//what if cout<<c3<<c2;
class CComplex { class CComplex {
friend ostream& operator<<( friend ostream& operator<<(
ostream& out, CComplex& c) { ostream& out, CComplex& c) {
out << “(” << c.real << “,” out << “(” << c.real << “,”
<< c.imag << “i)” << endl; << c.imag << “i)” << endl;
return out; } return out; }
}; };
Hung-Pin(Charles) Wen UEE1303(1070) L05 35 Hung-Pin(Charles) Wen UEE1303(1070) L05 36
Example of Overloading >> Overload Array Operator []

 Overloading operator >> on CComplex  Can overload [] for your class


class CComplex {
–typically, X[i]*(X+i)
friend istream& operator>>(
istream& inp, CComplex& c) { –used to check out-of-bound
inp >> c.real >> c.imag; –a binary operator: the left operand is a
return inp;
} reference object + the right one is an
}; integer
//in main(){}  Format
CComplex c1, c2, c3; –operator must return a reference
cin >> c1 >> c2;
–operator [] must be a member function
c3 = c1 + c2;
cout << c1 << c2 << c3; 〈cname〉& 〈cname〉::operator[](int i)
{ //functional body; }
Hung-Pin(Charles) Wen UEE1303(1070) L05 37 Hung-Pin(Charles) Wen UEE1303(1070) L05 38

Example of Overloading [] (1/2) Example of Overloading [] (2/2)

 Recall CStr() example in Lecture 03 char& CStr::operator[](int i) {


if (i>=strlen(line)) {
class CStr lec5-7.cpp cerr << “Error: ” << i <<
{
“ is out of bound!!!” << endl;
private:
}
char * line;
return line[i];
public:
};
CStr(char* word); lec5-7.cpp
CStr(const CStr & old); int main() {
... CStr one(“lec5-7”); //call constructor
cout << one[5] << endl; //what happens?
//overloading [] as a member function cout << one[8] << endl; //what happens?
char & operator[](int i); return 0;
}; }
Hung-Pin(Charles) Wen UEE1303(1070) L05 39 Hung-Pin(Charles) Wen UEE1303(1070) L05 40
Type Casting for Class (1/2) Type Casting for Class (2/2)

 C++ provides explicit type conversion  What if converting a CComplex into a double?
– 〈datatype〉(〈data〉), ex: int(82.7) –need a type-conversion function
– (〈datatype〉)〈data〉, ex: (double)49
–format: 〈cname〉::operator〈datatype〉 ()
 Conversion constructor casts the data of one { //functional body; }
 Example
type into an object of another class, ex:
class CComplex {
–can have only one parameter  why? operator double() { return real; }
class CComplex { };
CComplex(double r) {
real = r; imag = 0; }
–cannot assign the returned datatype
}; –cannot have any parameter
CComplex o1(4.2); CComplex o1(4.2); double d2 = 12;
CComplex o2 = o1 + CComplex(2.5); double d3 = d2 + o1; //double operator +
Hung-Pin(Charles) Wen UEE1303(1070) L05 41 Hung-Pin(Charles) Wen UEE1303(1070) L05 42

Summary (1/2) Summary (2/2)

 C++ built-in operators can be overloaded  friend functions add efficiency only

–to work with objects of your class –not required if sufficient accessors and
mutators are available
 Operators are really just functions
 Reference "names" a variable with an alias
 friend functions have direct private
 References and more overloading
member access
–operators: = , [], ++, --
 Operators can be overloaded as  Can overload << and >>
member functions where
–return type is a reference to stream type
–the first operand is the calling object

Hung-Pin(Charles) Wen UEE1303(1070) L05 43 Hung-Pin(Charles) Wen UEE1303(1070) L05 44

You might also like