目录
引入运算符重载
在使用类对象的时候,会发现同类的对象和对象之间没有办法像整形和浮点型那样子进行快速的运算操作,需要对象和对象之间运算的时候,总是要进行非常繁琐的操作,所以引入了运算符的重载,以简化类对象在使用时的操作,提高开发效率
运算符重载注意事项:
格式:
类内定义:
返回值类型 operator 运算符(形参)
{
}
类外定义:
类内声明:返回值类型 operator 运算符(形参);
类外定义:返回值类型 类名::operator 运算符(形参)
{
}
1、运算符的重载必须是已有的运算符,不能随意创造。
2、重载运算符不能改变原有运算符的规则和操作数。
3、重载后的功能要和原有的运算符功能一致,不要没有目的的重载运算符。
4、运算符重载最好有无参构造函数,因为在计算的过程中有可能会用到临时对象
5、重载后使用运算符的时候就相当于调用了运算符重载函数 a+b a.operator +(b)
6、有一些运算符不允许重载:
成员访问符号:.
计算内存: sizeof
三目运算符:?:
限定符: ::
运算符重载的实现
需要构造函数来实现,可以构造成员函数或类外友元函数来实现。
例:
实现类对象的 + 操作
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
Point operator +(const Point &p1); //函数声明
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
Point Point::operator +(const Point &p1) //运算符‘+’重载函数定义
{
return Point(xp + p1.xp,yp + p1.yp);
}
int main()
{
Point a(2,6);
Point b(2,4);
Point c = a+b; //类对象相加
c.show();
return 0;
}
实现类对象的 += 操作
运算结束后,将值存入调用函数的对象。
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
Point operator +=(const Point &p1); //函数声明
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
Point Point::operator +=(const Point &p1) //运算符‘+=’重载函数定义
{
xp = xp + p1.xp;
yp = yp + p1.yp;
return *this;
}
int main()
{
Point a(1,2);
Point b(3,4);
Point c;
c = a+=b; //分解为a = a+b; c = a;
a.show();
c.show();
return 0;
}
实现类对象的 ++ 操作
实现类似 a++,++a的操作
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
Point operator ++(void); //函数声明
Point operator ++(int n); //函数声明
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
Point Point::operator ++(void) //运算符在前
{
xp++;
yp++;
return *this;
}
Point Point::operator ++(int n) //运算符在后
{
Point a = *this;
xp++;
yp++;
return a;
}
int main()
{
Point a,b,c;
b = a++; //先赋值给b,后++
c = ++a; //先++,后赋值给c
b.show();
c.show();
return 0;
}
实现类对象的 == 判断
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
bool operator ==(const Point &p1); //函数声明
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
bool Point::operator ==(const Point &p1) //判断是否相等,函数定义
{
if(xp == p1.xp && yp == p1.yp)
{
return 1; //ture
}
else
{
return 0; //fasle
}
}
int main()
{
Point a(1,2);
Point b(1,2);
if(a == b) //调用 '==' 符号
cout <<"相等";
else
cout <<"不相等";
return 0;
}
实现类对象与常数 + 操作
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
Point operator +(int n); //函数声明
friend Point operator +(int n,Point &p1); 声明友元函数
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
Point Point::operator +(int n) //类对象调用运算符
{
return Point(xp + n,yp + n);
}
Point operator +(int n,Point &p1) //常量调用运算符
{
Point a;
a.xp = p1.xp + n;
a.yp = p1.yp + n;
return a;
}
int main()
{
Point a;
int b = 5;
a = a+5;
a.show();
a = 5+a;
a.show();
return 0;
}
实现类对象的 cin cout 操作
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
Point(int x=0,int y=0):xp(x),yp(y){
}
void show(void);
friend istream & operator >>(istream &is,Point &p1); //声明友元函数
friend ostream & operator <<(ostream &os,Point &p1); //声明友元函数
};
void Point::show(void)
{
cout << "xp:" << xp <<" "<< "yp:" << yp << endl;
}
/************************************
* 返回值:istream &
* 函数名:operator >>
* 形参:istream &is,Point &p1
************************************/
istream & operator >>(istream &is,Point &p1) //类对象输入函数声明
{
cout << "请输入第一个参数:";
is >> p1.xp;
cout << "请输入第二个参数:";
is >> p1.yp;
return is;
}
/************************************
* 返回值:ostream &
* 函数名:operator <<
* 形参:ostream &os,Point &p1
************************************/
ostream & operator <<(ostream &os,Point &p1) //类对象输出函数声明
{
os << "xp:" << p1.xp <<" ";
os << "yp:" << p1.yp << endl;
return os;
}
int main()
{
Point a;
cin >> a; //类对象进行整体输入值
cout << a; //整体输出
return 0;
}
成员函数和友元函数选择的问题
通过上述例子可以发现,重构只有类对象调用的运算符时,一般采用成员函数,这样子可以少传一个参数,因为在对象调用成员函数时,this指针会自动指向对象的成员,所以不需要传对象的参数。
而重构需要非类对象调用的运算符时,需要定义友元函数,因为非类对象无法调用成员函数,只能通过声明友元函数的方法去调用类内的成员。