前言
但在C++中,直接将+或-用于复数是不允许的。
代码更容易理解
例如:
bool compareQuata = Bill < Jimmy
/*Bill和Jimmy是CMan的两个对象
比较他们的体重指数*/
complex_a + complex_b
/*complex_a和complex_b是两个复数对象
求两个复数的和*/
提示:以下是本篇文章正文内容,下面案例可供参考
一、运算符重载的概念
int x , y
y = x + y ;
对于复数加法来说,有:
complex c1 , c2 ; // 复数类对象
c1 = c1.Cadd (c2 ) ; // 调用函数计算两个复数的和
对于矩阵加法来说,有:
matrix m1 , m2 ; // 矩阵类对象
m1 = m1.Madd ( m2 ) ;// 调用函数计算两个矩阵的和
能否表示为
c1 = c1 + c2 ;
m1 = m1+m2;
例子:
#include<iostream>
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0);
CComplex& addComplexToItself(const CComplex &r_c);
void print() const;
};
int main(){
CComplex a(3, 4), b(5, 6);
a = a.addComplexToItself(b);
//a += b; // error, 运算符’+=’没有被重载
a.print();
}
/
#include<iostream>
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0):real(r),image(i){cout<<"constructor"<<endl;}
CComplex& addComplexToItself(const CComplex &r_c)
{ real += r_c.real; image += r_c.image; return *this; }
void print() const{
if(real){
cout<<real;
if(image>0)
cout<<"+";
}
if(image){
if(abs(image)!=1)
cout<<image;
if(image==-1)
cout<<"-";
cout<<"i";
}
if(real==0 && image==0)
cout<<0;
cout<<endl;
}
};
int main(){
CComplex a(3, 4), b(-3, -14);
a = a.addComplexToItself(b);
//a += b; // error, 运算符’+=’没有被重载
a.print();
}
问题讨论:
CComplex类定义了一个addComplexToItself()成员函数实现复数类对象的自增运算。
基本数据类型变量的自增可以用’+=’运算符实现。
能否直接对一个CComple类对象进行’+=’运算? 如a += b?
运算符重载的实现:
运算符重载举例:
CComplex类定义一个运算符重载函数:
CComplex& operator +=
(const CComplex& r_c)
![](https://i-blog.csdnimg.cn/blog_migrate/83941b3970cb6755ba5dd61829e4040e.png)
例子:
#include<iostream>
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0):real(r),image(i){cout<<"constructor"<<endl;}
CComplex& operator +=(const CComplex &r_c)
{ real += r_c.real; image += r_c.image; return *this; }
void print() const{
if(real){
cout<<real;
if(image>0) cout<<"+"; }
if(image){
if(abs(image)!=1)cout<<image;
if(image==-1)cout<<"-";
cout<<"i"; }
if(real==0 && image==0)
cout<<0;
cout<<endl;
}
};
int main(){
CComplex a(3, 4), b(-3, -14);
a += b;
a.print();
}
运算符重载的限制:
只能重载已经存在的C++运算符。
运算符重载不能改变运算符操作数的个数、优先级和结合性。
二、运算符重载函数作为类成员函数
实现
说明 :
编译程序处理成员函数时,为它设置了一个this指针。
所指的参数(自身的参数)
二元运算符以成员函数形式重载,左操作数必须为类对象,目标对象作为左操作数。
声明格式:
成员运算符重载函数在类中的声明格式为:
class X
{ ……
<返回数据类型> operator <运算符> (<参数表>);
};
成员运算符重载函数在类外定义的格式为:
<返回数据类型> X::operator <运算符> (<参数表>)
{
<函数体>
}
程序:
#include<iostream>
using namespace std;
class CComplex{
private:
double real, image;
public:
CComplex(double a=0.0, double b=0.0)
{ real = a; image = b; }
CComplex(const CComplex &r)
{ real = r.real; image = r.image; }
void print() const;
const CComplex& operator+= (const CComplex &r_c);
const CComplex& operator+= (double c);//实部、虚部加c
CComplex operator+ (const CComplex &r_c) const;
CComplex operator+ (double c) const;
};
void CComplex::print() const{
cout<<"real="<<real<<",image="<<image<<endl;
}
const CComplex& CComplex::operator+= (const CComplex &r_c){
real+=r_c.real;
image+=r_c.image;
return *this;
}
const CComplex& CComplex::operator+= (double c)//实部、虚部加c{
{ real+=c;
image+=c;
return *this;
}
CComplex CComplex::operator+ (const CComplex &r_c) const{
double r,i;
r=real+r_c.real;
i=image+r_c.image;
return CComplex(r,i);
}
CComplex CComplex::operator+ (double c) const{
double r,i;
r=real+c;
i=image+c;
return CComplex(r,i);
}
int main(){
CComplex c1(1,2),c2(3,4),c3;
int c=5;
c1+=c2;
c1.print();
c1+=c;
c1.print();
c3=c1+c2;
c3.print();
c3=c1+c;
c3.print();
return 1;
}
三.读入数据
运算符重载函数可以用友元函数的形式来实现。
赋值运算符‘=’、下标运算符‘[ ]’、成员选择运算符‘->’和函数调用运算符‘()’、所有的类型转换运算符不能用友元函数形式重载。
声明格式:
友元运算符重载函数在类中的声明格式为:
class X {
……
friend <返回数据类型> operator <运算符> (<参数表>);
};
友元运算符重载函数在类外定义的格式为:
<返回数据类型> operator <运算符> (<参数表>)
{
<函数体>
}
程序:
#include<iostream>
using namespace std;
class CComplex{
private:
double real, image;
public:
CComplex(double a=0.0, double b=0.0)
{ real = a; image = b; }
CComplex(double c) { real = c; image = 0.0; }
void print() const;
friend void operator+= (CComplex &r_x, const CComplex &r_y);
friend CComplex operator+ (const CComplex &r_x, const CComplex &r_y);
};
void CComplex::print() const{
cout<<"real="<<real<<",image="<<image<<endl;
}
void operator+= (CComplex &r_x, const CComplex &r_y){
r_x.real+=r_y.real;
r_x.image+=r_y.image;
}
CComplex operator+ (const CComplex &r_x, const CComplex &r_y){
double r,i;
r=r_x.real+r_y.real;
i=r_x.image+r_y.image;
CComplex c(r,i);
return c;
}
int main(){
CComplex c1(1,2),c2(3,4),c3;
c1+=c2;
c1.print();
c3=c1+c2;
c3.print();
return 1;
}
一元运算符重载:
如同“++”运算符有前缀和后缀两种使用形式一样,“++”和“--”重载运算符也有前缀和后缀两种运算符重载形式,以“++”重载运算符为例,其语法格式如下:
<函数类型> operator ++(); //前缀运算
<函数类型> operator ++(int); //后缀运算
使用前缀运算符的语法格式如下:
++<对象>;
使用后缀运算符的语法格式如下:
<对象>++;
1.成员函数重载实例:
#include<iostream>
using namespace std;
class Increase{
private:
int value;
public:
Increase(int x):value(x){}
void display(){cout <<"value =" <<value <<endl; }
Increase & operator++(); //前增量
Increase operator++(int); //后增量
};
Increase & Increase::operator++()
{ value++; //先增量
return *this; //再返回原对象
}
Increase Increase::operator++(int)
{ Increase temp(*this); //临时对象存放原有对象值
value++; //原有对象增量修改
return temp; //返回原有对象值
}
int main()
{ Increase n(20);
n.display();
(n++).display();
//显示临时对象值
n.display();
//显示原有对象
++n;
n.display();
++(++n);
n.display();
}
运行结果:
value=20
value=20
value=21
value=22
value=24
2、友元函数重载示例:
#include<iostream>
using namespace std;
class Increase{
private:
int value;
public:
Increase(int x):value(x){}
friend Increase & operator++(Increase &); //前增量
friend Increase operator++(Increase &,int); //后增量
void display(){ cout <<"value=" <<value <<endl; }
};
Increase & operator++(Increase & a)
{ a.value++; //前增量
return a; //再返回原对象
}
Increase operator++(Increase& a, int)
{ Increase temp(a); //通过拷贝构造函数保存原有对象值
a.value++; //原有对象增量修改
return temp; //返回原有对象值
}
int main()
{
Increase n(20);
n.display();
(n++).display(); //显示临时对象值
n.display(); //显示原有对象
++n;
n.display();
++(++n);
n.display();
//(n++)++;
n.display();
}
编程练习题:
#include<iostream>
#include<iomanip>
using namespace std;
class Date{
int year,month,day;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
public:
Date(int y=0,int m=0,int d=0):year(y),month(m),day(d){}
void judge1(int y){
if(y%400==0 || (y%4==0 && y%100!=0))
days[2]=29;
else
days[2]=28;
}
long judge2(int y){
if(y%400==0 || (y%4==0 && y%100!=0))
return 366;
else
return 365;
}
Date operator+(int d){
Date t(*this);
d+=t.day;
judge1(t.year);
while(d>days[t.month]){
d-=days[t.month];
t.month++;
if(t.month==13){
t.month=1;
t.year++;
judge1(t.year);
}
}
t.day=d;
return t;
}
Date operator-(int d){
Date t(*this);
d=t.day-d;
judge1(t.year);
while(d<=0){
t.month--;
if(t.month==0){
t.month=12;
t.year--;
judge1(t.year);
}
d+=days[t.month];
}
t.day=d;
return t;
}
long operator-(const Date& date){
int startyear=year<date.year?year:date.year;
long sum1=day;
for(int i=startyear;i<year;i++)
sum1+=judge2(i);
judge1(year);
for(int i=1;i<month;i++)
sum1+=days[i];
long sum2=date.day;
for(int i=startyear;i<date.year;i++)
sum2+=judge2(i);
judge1(date.year);
for(int i=1;i<date.month;i++)
sum2+=days[i];
return sum1-sum2;
}
void print(){
cout<<year<<"-"<<setfill('0')<<setw(2)<<month<<"-"<<setfill('0')<<setw(2)<<day<<endl;
}
};
int main(){
Date d1(2022,12,31),d2(2022,1,1),d3;
d3=d1+1;
d3.print();
d3=d2-1;
d3.print();
cout<<d1-d2<<endl;
}
四、类型转换
标准类型是除class、struct和union类型外的其他所有类型。