[note 1]
The operators that can only be overloaded as non-static member function of some classes:
= , [] , () , ->
(As for the static function, it doesn’t has the this pointer, so the operator can’t be overloaded as static member fuction of a class.)
[note 2]
Although the semantics of an operator can be extended, we can’t change its syntax.
[note 3]
The general form of an operator function:
return-type classname::operator op (argument-list)
{
Function body
}
[note 4]
The process of operator overloading:
- Create a class that defines the data type that is to be used in the overloading operation.
- Declare the operator function on the public part of the class. (It may be a member function or a friend function.)
- Define the operator function to implement the required operations.
[note 5]
[Example] Shows how the unary minus operator is overloaded.
#include <iostream>
using namespace std;
class space
{
int x,y,z;
public:
void getdata(int a, int b, int c);
void display(void);
void operator-(); //Overload unary minus as non-static member function
};
void space::getdata(int a, int b, int c){x=a; y=b; z=c;}
void space::display(void)
{
cout << x << " ";
cout << y << " ";
cout << z << "\n";
}
void space::operator -(){x=-x; y=-y; z=-z;}
int main()
{
space S;
S.getdata(10,-20,30);
cout << "S : ";
S.display();
-S; //Activates operator-() function
cout << "S : ";
S.display();
return 0;
}
output:
S : 10 -20 30
S : -10 20 -30
[note 6]
[example 2]
#include <iostream>
using namespace std;
class space
{
int x,y,z;
public:
void getdata(int a, int b, int c);
void display(void);
space& operator-(); //Overload unary minus as non-static member function
};
void space::getdata(int a, int b, int c){x=a; y=b; z=c;}
void space::display(void)
{
cout << x << " ";
cout << y << " ";
cout << z << "\n";
}
//return a value
space& space::operator -(){x=-x; y=-y; z=-z; return *this;}
int main()
{
space S;
S.getdata(10,-20,30);
cout << "S : ";
S.display();
-S; //Activates operator-() function
cout << "S : ";
S.display();
space M;
M=S;
cout<<"M:";
M.display();
return 0;
}
[note 7]
[example 3] operation overloading with friend function
#include <iostream>
using namespace std;
class Complex
{
double r,i;
public:
Complex(double R=0,double I=0):r(R),i(I){};
friend Complex operator+(Complex a,double b){return Complex(a.r+b,a.i);}
friend Complex operator+(double a,Complex b){return Complex(a+b.r,b.i);}
void display();
};
void Complex::display()
{
cout << r;
if(i>0) cout << "+";
if(i!=0) cout << i << "i" << endl;
}
int main()
{
Complex c1(1,2),c2;
c2=c1+5;
c2.display();
c2=5+c1;
c2.display();
return 0;
}
[note 8]
There are certain situations where we would like to use a friend function rather than a member function:
- We need to use two different types of operands for a binary operator, one an object and another a built-in type data.
[example 4]
#include <iostream>
class Complex
{
double r,i;
public:
Complex(double R=0,double I=0):r(R),i(I){};
friend Complex operator+(Complex a,double b){return Complex(a.r+b,a.i);}
friend Complex operator+(double a,Complex b){return Complex(a+b.r,b.i);}
void display();
};
void Complex::display()
{
std::cout << r;
if(i>0) std::cout << "+";
if(i!=0) std::cout << i << "i" << std::endl;
}
int main()
{
Complex c1(1,2),c2;
c2=c1+5;
c2.display();
c2=5+c1;
c2.display();
return 0;
}
[note 9]
If the operator is overloaded as a postfix operator, a useless argument is inserted to the argument list.
[note 10]
Overloading of assignment operator(=)
- The assignment operator can only be overloaded as member function and can’t be friend dunction.
- The assignment operator overloaded inside the class can’t be inherited.
[example 5]
#include <iostream>
#include <string>
using namespace std;
class String
{
char *ptr;
int n;
public:
String(char * s,int a)
{
ptr=new char[strlen(s)+1];
strcpy(ptr,s);
n=a;
}
String& operator=(const String& s); //Overload the assignment operator
~String(){delete ptr;}
void print(){cout<<ptr<<endl;}
};
String& String::operator=(const String& s)
{
if(this==&s) return *this;
delete ptr;
ptr=new char[strlen(s.ptr)+1];
strcpy(ptr,s.ptr);
return *this;
}
int main()
{
String p1("Hello",8);
{
String p2("chong qing",10);
p2=p1;
cout<<"p2:";
p2.print();
}
cout<<"p1:";
p1.print();
return 0;
}
[note 11]
Overloading of subscript operator([])
- [] can only be overloaded as non-static member function, it can’t be overloaded as friend functions.
[example 6]
#include <iostream>
#include <string>
using namespace std;
struct Person //Structure of information of person
{
double salary;
char *name;
};
class SalaryManage
{
Person *employ; //Array to save the information of person
int max; //Upper bound of array index
int n; //Actual number of person in the array
public:
SalaryManage(int Max=0)
{
max=Max;
n=0;
employ=new Person[max];
}
double &operator[](char *Name) //Overload[] and return reference
{
Person *p;
for(p=employ;p<employ+n;p++)
if(strcmp(p->name,Name)==0)
return p->salary;
p=employ + n++;
p->name=new char[strlen(Name)+1];
strcpy(p->name,Name);
p->salary=0;
return p->salary;
}
void display() //Display the name and salary of all the person
{
for(int i=0;i<n;i++)
cout<<employ[i].name<<" "<<employ[i].salary<<endl;
}
};
int main()
{
SalaryManage s(3);
s["Anita"]=2188.88; //[] is overloaded to the function that return reference and then it can appear on the left of the operator =
s["Carol"]=1230.07;
s["Emily"]=3200.97;
cout<<"Anita\t"<<s["Anita"]<<endl; //Return Angela's salary
cout<<"Carol\t"<<s["Carol"]<<endl;
cout<<"Emily\t"<<s["Emily"]<<endl;
cout<<"-----Output of display are illustrated as follows--------\n\n";
s.display();
return 0;
}
[note 12]
Overloading of output operator (<<) and input operator (>>)
- Note that it can only be overloaded as the friend function of the class.
[Form]:
ostream & operator << (ostream &os, classtype object)
{
...
os<<...
return os;
}
istream & operator >> (istream &is, classtype& object)
{
...
is>>...
return is;
}
[note 13]
There are some operators that can’t be overloaded:
. |
---|
.* |
:: |
?: |
There are some operators can’t be overloaded by using friend function:
= |
---|
() |
[] |
-> |
There are some operators must be overloaded by using friend function:
>> |
---|
<< |
[note 14]
When using binary operators overloaded through a member function, the left-hand operand must be an object of the relevant class.
[note 15]
Type conversion – Basic to class type
[1]
string s1,s2;
char* name1="hello";
char* name2="hangzhou";
s1=string(name1); //L5
s2=name2; //L6
- Line 5 and 6 first convert name1 from char* type to string and then assign the string type values to the object.
[2]
We can also accomplish this conversion using an overloaded = operator.
[note 16]
Type conversion – class to basic type
We can do the conversion by using casting operator function.
The casting operator function should satisfy the following conditions:
- It must be a class member
- It must not specify a return type
- It must not have any arguments
- It must return the data of the type being converted.
//[convert from string to char*]
string:: operator char*()
{
return (p);
}
[note 17]
Type conversion – one class to another class
Such convertion can be carried out by either a constructor or a conversion function.