目录
-
5.2 运算符重载
【C++运算符重载规则】
(1)不能重载的运算符
【 . 】 成员访问运算符
【 .* 】成员指针运算符
【 :: 】作用域运算符
【Sizeof】长度运算符
【?:】条件运算符
(2)运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造,与原有功能相似
(3)重载不能改变运算符的操作对象(即操作数)的个数
(4)重载不能改变运算符原有的优先级
(5)重载不能改变运算符原有的结合特性
(7)运算符重载函数的参数至少应有一个是类对象
-
5.2.1 在类外定义的运算符重载函数
【示例】
/*****************************/
/*在类外定义的运算符重载函数 */
/*****************************/
#include<iostream>
using namespace std;
class Complex{
public:
double real;
double imag;
Complex(double r=0,double i=0){ //定义带有默认值的构造函数
real=r;
imag=i;
}
};
Complex operator+(Complex op1,Complex op2){ //重载运算符 " + "
Complex temp;
temp.real=op1.real+op2.real; //两个对象成员变量相加
temp.imag=op1.imag+op2.imag;
return temp; //返回值为Complex类型
}
int main()
{
Complex com1(1.1,2.2),com2(3.3,4.4);
Complex total_fir,total_sec;
total_fir=operator+(com1,com2); //第一种调用语句
cout<<"total_fir.real = "<<total_fir.real<<" "<<"total_fir.imag = "<<total_fir.imag<<endl;
total_sec=com1+com2; //第二种调用语句
cout<<"total_sec.real = "<<total_fir.real<<" "<<"total_sec.imag = "<<total_sec.imag<<endl;
return 0;
}
【运行结果】
【缺点】只能访问类中的公有数据成员,而不能访问类中私有数据成员,故引入友元运算符重载函数
-
5.2.2 友元运算符重载函数
1、友元双目运算符重载函数
【友元双目运算符重载函数调用方法】
(1)隐式调用:obj1@obj2;
(2)显示调用:operator@(obj1,obj2);
【友元双目运算符重载函数示例】
/*****************************/
/*****友元运算符重载函数******/
/***** 双目运算符 ******/
/*****************************/
#include<iostream>
using namespace std;
class Complex{
public:
Complex(double r=0,double i=0); //声明带有默认值的构造函数
friend Complex operator+(Complex& op1,Complex& op2); //声明友元运算符重载函数
void show(Complex& total);
void show();
private:
double real;
double imag;
};
Complex::Complex(double r,double i){ //定义带有默认值的构造函数
real=r;
imag=i;
}
void Complex::show(Complex& total){
cout<<"友元运算符重载函数"<<"total.real = "<<total.real<<" "<<"total.imag = "<<total.imag<<endl;
}
void Complex::show(){
cout<<"友元运算符重载函数"<<"total.real = "<<this->real<<" "<<"total.imag = "<<(*this).imag<<endl;
}
Complex operator+(Complex& op1,Complex& op2){ //定义友元运算符重载函数
Complex temp;
temp.real=op1.real+op2.real; //两个对象成员变量相加
temp.imag=op1.imag+op2.imag;
return temp; //返回值为Complex类型
}
int main()
{
Complex com1(1.1,2.2),com2(3.3,4.4);
Complex total_fir,total_sec;
total_fir=operator+(com1,com2); //第一种调用语句
total_fir.show(total_fir);
total_sec=com1+com2; //第二种调用语句
total_sec.show();
return 0;
}
【双目运算符重载函数示例运算结果】
2、友元单目运算符重载函数
【友元单目运算符重载函数调用方法】
(1)隐式调用:@obj;
(2)显示调用:operator@(obj);
【友元单目运算符重载函数示例】
/*****************************/
/*****友元运算符重载函数******/
/***** 单目运算符 ******/
/*****************************/
#include<iostream>
using namespace std;
class Coord{
public:
Coord(int x1=0,int y1=0)
{
x=x1;
y=y1;
}
friend Coord operator-(Coord &obj);
void print();
private:
int x,y;
};
Coord operator-(Coord &obj){ //友元单目运算符重载
//函数形参是对象的引用
obj.x=-obj.x;
obj.y=-obj.y;
return obj;
}
void Coord::print(){
cout<<"x = "<<x<<endl;
cout<<"y = "<<y<<endl;
cout<<endl;
}
int main()
{
Coord obj1(100,200),obj2;
obj1.print();
obj2=-obj1; //第一种调用单目运算符重载函数
obj2.print();
obj2=operator-(obj1); //第二种调用单目运算符重载函数
obj2.print();
return 0;
}
【友元单目运算符重载函数示例运算结果】
3、友元运算符重载函数使用说明
(1)运算符重载函数operator@可以返回任何类型,通常返回与他所操作的类的类型相同
(2)赋值运算符“=”,下标运算符“[ ]”,函数调用运算符“()”不能定义为友元运算符重载函数
-
5.2.3 成员运算符重载函数
【定义】把运算符重载函数定义成某个类的成员函数,称为成员运算符重载函数。
【语法形式】
(1)在类的内部,定义成员运算符重载函数
//类内部定义成员运算符重载函数
函数类型 operator 运算符(形参表)
{
函数体
}
(2)在类中声明,在类外定义
//类内部声明,类外定义成员运算符重载函数
Class X{
//.....
函数类型 operator 运算符(形参表) //类内声明
//.....
}
函数类型 X::operator 运算符(形参表) //类外定义
{
函数体
}
【语法形式说明】在成员运算符重载函数形参表中,若运算符是单目的,则参数表为空;若运算符是双目的,则参数表中有一个操作数。
1、成员双目运算符重载函数
【成员双目运算符重载函数示例】
/*****************************/
/*****成员运算符重载函数******/
/***** 双目运算符 ******/
/*****************************/
#include<iostream>
using namespace std;
class Complex{
public:
Complex(double r=0,double i=0); //声明带有默认值的构造函数
Complex operator+(Complex& op1); //声明友元运算符重载函数
void show();
private:
double real;
double imag;
};
Complex::Complex(double r,double i){ //定义带有默认值的构造函数
real=r;
imag=i;
}
Complex Complex::operator+(Complex& op1){ //定义成员运算符重载函数
Complex temp;
temp.real=real+op1.real; //两个对象成员变量相加
temp.imag=imag+op1.imag;
return temp; //返回值为Complex类型
}
void Complex::show(){
cout<<"成员运算符重载函数"<<"total.real = "<<this->real<<" "<<"total.imag = "<<(*this).imag<<endl;
}
int main()
{
Complex obj1(1.1,2.2),obj2(3.3,4.4),obj3,obj4;
obj3=obj1+obj2; //隐式调用
obj4=obj1.operator+(obj2); //显示调用
obj1.show();
obj2.show();
obj3.show();
obj4.show();
return 0;
}
【成员双目运算符重载函数示例运行结果】
【成员双目运算符重载函数调用方法】
obj1@obj2; //隐式调用
obj1.operator@(obj2) //显示调用
2、成员单目运算符重载函数
【成员单目运算符重载函数示例】
/*****************************/
/*****成员运算符重载函数******/
/***** 单目运算符 ******/
/*****************************/
#include<iostream>
using namespace std;
class Coord{
public:
Coord(int i=0,int j=0);
void print();
Coord operator++(); //声明运算符++重载函数
private:
int x,y;
};
Coord::Coord(int i,int j){
x=i;
y=j;
}
void Coord::print(){
cout<<"x = "<<x<<" , y = "<<y<<endl;
}
Coord Coord::operator++(){ //定义运算符++重载函数
++x;
++y;
return *this; //返回当前对象的值
}
int main()
{
Coord obj(10,20);
obj.print();
++obj; //隐式调用
obj.print();
obj.operator++(); //显示调用
obj.print();
return 0;
}
【成员单目运算符重载函数示例运行结果】
【成员单目运算符重载函数调用方法】
@obj1 //隐式调用
obj1.operator@() //显示调用
-
5.2.4 成员运算符重载函数与友元运算符重载函数的比较
(1)对于双目运算符,成员运算符重载函数参数表含有一个参数,而友元运算符重载函数参数表中含有两个参数
对于单目运算符,成员运算符重载函数参数表中没有参数,而友元运算符重载函数参数表含有一个参数
(2)一般情况下,双目运算符可以被重载为友元运算符函数或成员运算符重载函数
但存在例外必须使用友元函数,当一个自定义类型的对象变量,与C++原有类型变量做操作的时可能发生错误
【必须使用友元运算符重载函数示例】
/*************************************/
/*****必须使用友元运算符重载函数******/
/********* 双目运算符 **********/
/*************************************/
//【注】" + "是左操作数
#include<iostream>
using namespace std;
class Complex{
public:
Complex(int sub_real=0,int sub_image=0){
real=sub_real;
image=sub_image;
}
friend Complex operator+(Complex com,int a){ //运算符+的左侧是类对象,右侧是整数
return Complex(com.real+a,com.image);
}
friend Complex operator+(int a,Complex com){ //运算符+的左侧是整数,右侧是类对象
return Complex(com.real+a,com.image);
}
void show(){
cout<<" real = "<<real<<" image = "<<image<<endl;
}
private:
int real;
int image;
};
int main()
{
Complex obj_com1(30,40),obj_com2;
obj_com2=obj_com1+30;
obj_com2.show();
obj_com2=50+obj_com1;
obj_com2.show();
return 0;
}
【必须使用友元运算符重载函数示例运行结果】