- Giving a special additional meaning to operator
- Overloading is not possible for the following
- Class member operators (.,.*)
- Scope resolution operator (::)
- Size operator:(sizeof)
- Conditional Operator(?:)
- Semantics of an operator is changed but neither the syntax nor the precedence is changed
- The original meaning is not lost
Operator Function
- return-type classname :: operator <op>(arg list)
- operator <op> is the function name
- Operator functions must be either (non static) member functions or friend functions
- Objects used to invoke operator is passed implicitly the operator function
- So friend need one more argument!
- Passing by value or passing by variable accepted
- The interpretation is like a function only
Overloading minus operator (-)
class space
{ int x,y,z;
public:
void getdata(int a, int b, int c);
void display(void);
void operator-(); }
void space :: operator –()
{ x = -x; y = -y; z = -z; }
main ()
{ space s; s.getdata(10,-20,30); s.display();
-s; s.display(); }
Overloading Using a Friend
friend void operator – (space & s); //declaration
void operator –(space & s) // definition
{ s.x = -s.x; s.y = -s.y; s.z = -s.z; }
- If we do not use reference parameter, the changes in the operator function will not be reflected
- For some situations, friends are more useful
- When manipulating an object with a pure data
- When dealing with different type of objects
- Some operators { =,(),[],-> } can not be overloaded as friends, though allowed as member
Overriding plus operator (+)
class complex
{ float x,y;
public : ….
// complex sum (complex c)
complex operator+(complex c)
{ complex temp;
temp.x = x + c.x; temp.y = x + c.y; return temp}
main();
{ complex c1,c2,c3;
// c3 = c1.sum(c2);
c3 = c1 + c2; }
Using Friend For +
complex() {}// a default constructor
complex(float r, float i)//constructor
{ real = r; imag = i; }
//friend complex sum (complex c1,complex c2)
friend complex +(complex c1,complex c2)
{ return complex((a.x+b.x),(a.y+b.y)) }
main()
{ complex c1,c2,c3;
// c3 = sum(c1,c2);
c3 = c1 + c2;
}
Overloading in Vector
class vector
{ int v[3];
public :
vector() {for v[i] = 0; }
vector(int *x) { for (int i=0;i<3;i++) v[i] = x[i]}
// friends declarations come here };
vector operator *(int a, vector b)
{vector c; for (int i=0;i<3;i6++) {c.v[i]=b.v[i]*a;}
vector operator *(vector b, int a) // same code
main() { vector m; vector n = {1,2,3}; int num=5;
vector p = m * num; vector q = 5 * n;
Overloading << and >>
istream & operator >> (istream & din, vector & b)
{for (int i=0;i<3;i++) din >> b.v[i]; return din; }
ostream & operator << (ostream& dout,vector& b)
{dout <<“(“ << b.v[0];
for (int i=1;i<3;i++) dout << “,” << b.v[i];
dout << “)”; }
cin >> p; // here p is a vector
cout << “p=“ << p;
- istream and ostream are classes defined in iostream.h file, they are input and output streams
Manipulating Strings
class string
{char *p; int len;
public : string() {p = NULL, len = 0}
string(char *x) { len= strlen(char *x);
p = new char(len + 1); }
string (const string & s) {len = strlen(s);
p = new char(len+1); strcpy(s,p);}
friend string operator +(string s1, string s2)
{ string temp; temp.len = s1.len + s2.len;
temp.p = new char(len + 1); strcpy(s1.p,temp.p); strcat(temp.p,s2.p); return temp }
friend int operator <=(string s1,string s2)
{ return (s1.len <= s2.len); }
ostream & operator <<(ostream & dout, string s)
{ dout << s.p ; return dout; }
main()
{ string s1 = “New” //second constructor
string s2 = string(“York”) // second constructor
string t1,t2,t3,t4; // first constructor
t1 = s1; t2 = s2; t3 = t1+t2; t4 = t1+t3;
if (t3 <= t4) cout << t3 << “ < or = “ << t4;
}
Rules for Overloading Operators
- The oo must have one userdefined type as arg
- Basic meaning of an op can not be changed (+-)
- Only existing operators can be overloaded, new ones can not be created
- When using binary oo by member functions, the lhs operator must be object of the relevant class
- Binary arithmetic ops must explicitly return a value, and not change values of arguments
- Some ops can not be simply overloaded
Type Conversions
- C’s and C++’s built-in data conversion routines for expressions and assignment
- int to float and float to int conversions
- Copying bit by bit for objects of compatible type
- Compiler does not support for incompatible types
- Three situations for incompatible matches
- From built in type to a class type
- From class type to built-in type
- From one class type to another class type
Basic to Class Type
- Constructors to convert from basic types to class types are quite common
class time
{ int hrs; int mins;
public : time (int t)
{ hrs = t / 60;
mins = t % 60; } };
main() {
int duration = 85;
time T1 = duration; // conversion}
Class to Basic Type
- Overloading a casting operator function
- operator <type name> () { … }
vector::operator double()
{ double sum = 0;
for (int i =0; i <size; i++)
sum +=v[i]*v[i];
return sqrt(sum) }
double length = double(v1) or v1// con to double
operator char*() {return (p);}
string s = “New”; char *q=s; //converts to char*
One Class to Another Class Type
- Obj_X = Obj_Y; here Obj_Y is a source class and Obj_X is a destination class
- If conversion to take place in a source class, it is done as a conversion fun. otherwise cons is used
- In the casting op function the type name may be built-in or may be user defined (class name)
- In operator type_name(), the type_name will be the destination class
- For the cons case the arg is the source class
Data Conversion, the Source Class
class invent1
{ int code; int items; float price;
public invent1(int a, int b, float c)
{ code = a; items = b; price = c; }
void putdata() {//print all data}
int getcode() { return code;}
int getitems() { return items;}
int getprice() { return price;}
operator invent2()
{ int c = code; float v = price * itmes;
return invent2(c,v); }
Data Conversion, the Dest Class
class invent2
{ int code; float value;
public : invent2() {code = 0; value = 0;}
invent2(int c, float v) {code = c; value = v;}
void putdata(){//putting all values!}
invent2(invent1 in) // this is conversion function
{ code = in.getcode();
value = in.getitems() * in.getprice(); };
main()
{ invent1 s1(100,5,140.0); invent2 d1;
d1 = s1; // here the conversion takes place!
Note for Overloading ++ and --
- In old C++, for overloading prefix and postfix versions of ++ and - -, there was no diff.
- operator - -() or ++() is to be used for prefix version now
- operator - -(int not_used) and ++(int not_used) for postfix version
- i.e. it is possible to overload a++ and ++a to do different jobs now! but that will be against the spirit of C++