运算符重载的进一步讨论
运算符重载函数作为类的成员函数
和友元函数
重载类型 | 声明方式 | 定义方式 | 参数 |
---|---|---|---|
普通函数 | 类外 | 类外 | 参数个数 = 原操作数个数 |
成员函数 | 类内 | 类内、类外 | 参数个数 = 原操作数个数-1 后置++、- -除外 左操作数必须是对象 |
友元函数 friend | 类内 | 类内、类外 | 参数个数 = 原操作数个数 注意实参与形参类型一一对应 左、右至少有一个是对象 |
- 由于使用友元会破坏类的封装,要尽量将运算符重载函数定义为成员函数
- 一般将
单目运算符
重载为成员函数
,将双目运算符
重载为友元函数
双目
:运算符左、右两边的操作数均参加运算。
重载运算符的规则
- C++只允许已有的部分运算符实施重载。
- 不能重载的运算符有五个。
- 重载不改变操作数的个数。
- 重载不改变运算符的优先级。
- 运算符重载函数不能带默认值参数。
- 运算符重载函数必须与自定义类型的对象联合使用,其参数至少有一个类对象或类对象引用(类对象别名)。
- C++默认提供 = 和 & 运算符重载。
- 运算符重载函数可以是类成员函数也可以是类的友元函数,还可以是普通函数。
- C++规定赋值运算符、下标运算符、函数调用运算符必须定义为类的成员函数;而输出流插入、输入流提取、类型转换运算符不能定义为类的成员函数。
实验一(复数加法)
实验内容
定义一个复数类Complex,重载运算法“+”,使之能用于复数的加法运算。将运算符重载为普通函数(非成员、非友元)、成员函数、友元函数。
根据要求修改
通过函数来实现复数相加的示例,分别编写程序,求两个复数之和。
代码展示
需要修改的原代码
#include <iostream>
using namespace std;
class Complex //定义Complex类
{public:
Complex(float x=0,float y=0){real=x;imag=y;} //构造函数
Complex complex_add(Complex &c2); //声明复数相加函数
void display() { cout<<real<<'+'<<imag<<'i'<<endl; };
private:
float real; //实部
float imag; //虚部
};
Complex Complex::complex_add(Complex &c2)
{ Complex c;
c.real = real +c2.real;
c.imag=imag+c2.imag;
return c;
}
int main()
{ Complex complex1(3.34, 4.8), complex2(12.8, 5.2);
Complex complex; //定义3个复数对象
complex=complex1.complex_add(complex2); // 进行两个复数的加运算
complex.display( );
return 0;
}
重载为普通函数
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(float x=0,float y=0){real=x;imag=y;}
void display(){ cout<<real<<'+'<<imag<<'i'<<endl; };
float real;
float imag;
};
Complex operator+(Complex&c1,Complex &c2)
{
Complex c;
c.real=c1.real+c2.real;
c.imag=c1.imag+c2.imag;
return c;
}
int main()
{
Complex complex1(3.34, 4.8), complex2(12.8, 5.2);
Complex complex;
complex=complex1+complex2;
complex.display( );
return 0;
}
重载为成员函数
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(float x=0,float y=0){real=x;imag=y;}
Complex operator+(Complex &c2);
void display(){ cout<<real<<'+'<<imag<<'i'<<endl; };
private:
float real;
float imag;
};
Complex Complex::operator+(Complex &c2)
{
Complex c;
c.real=real+c2.real;
c.imag=imag+c2.imag;
return c;
}
int main()
{
Complex complex1(3.34, 4.8), complex2(12.8, 5.2);
Complex complex;
complex=complex1+complex2;
complex.display( );
return 0;
}
重载为友元函数
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(float x=0,float y=0){real=x;imag=y;}
friend Complex operator+(Complex &c1,Complex &c2);
void display(){ cout<<real<<'+'<<imag<<'i'<<endl; };
private:
float real;
float imag;
};
Complex operator+(Complex &c1,Complex &c2)
{
Complex c;
c.real=c1.real+c2.real;
c.imag=c1.imag+c2.imag;
return c;
}
int main()
{
Complex complex1(3.34, 4.8),complex2(12.8, 5.2);
Complex complex;
complex=complex1+complex2;
complex.display( );
return 0;
}
实验结果
实验二
实验内容(复数除法)
定义一个复数类Complex,重载运算法“/”,使之能用于复数的除法运算。将运算符重载为普通函数(非成员、非友元)、成员函数、友元函数。分别编写程序,求两个复数之商。
代码展示
重载为普通函数
#include <iostream>
using namespace std;
class Complex
{
//运算符重载为普通函数时,不能够访问类内的私有成员,故将类的成员都定义为共有的
public:
Complex(float x=0,float y=0){real=x;imag=y;}
void display()
{
if (imag>0)
cout<<real<<'+'<<imag<<'i'<<endl;
else
cout<<real<<imag<<'i'<<endl;
}
float real;
float imag;
};
//运算符重载为普通函数时要有两个参数,此时不再有对类中数据成员的this指针
Complex operator/(Complex &c1,Complex &c2)
{
Complex c;
c.real=(c1.real*c2.real-c1.imag*c2.imag)/(c2.real*c2.real-c2.imag*c2.imag);
c.imag=(c1.real*c2.imag+c2.real*c1.imag)/(c2.real*c2.real-c2.imag*c2.imag);
return c;
}
int main()
{
Complex complex1(1,2),complex2(3,4),complex;
cout<<"complex1="; complex1.display();
cout<<"complex2="; complex2.display();
complex=complex1/complex2;
cout<<"complex=";
complex.display();
return 0;
}
重载为成员函数
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(float x=0,float y=0){real=x;imag=y;}
//运算符重载为类的成员函数
Complex operator/(Complex &c2);
void display()
{
if (imag>0)
cout<<real<<'+'<<imag<<'i'<<endl;
else
cout<<real<<imag<<'i'<<endl;
}
//类的成员函数可以调用类内的成员,所以可以将类的数据成员定义为私有的
private:
float real;
float imag;
};
Complex Complex::operator/(Complex &c2)
{
Complex c;
c.real=(real*c2.real-imag*c2.imag)/(c2.real*c2.real-c2.imag*c2.imag);
c.imag=(real*c2.imag+c2.real*imag)/(c2.real*c2.real-c2.imag*c2.imag);
return c;
}
int main()
{
Complex complex1(1,2),complex2(3,4),complex;
cout<<"complex1="; complex1.display();
cout<<"complex2="; complex2.display();
complex=complex1/complex2;
cout<<"complex=";
complex.display();
return 0;
}
重载为友元函数
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(float x=0,float y=0){real=x;imag=y;}
//运算符重载为类的友元函数
friend Complex operator/(Complex &c1,Complex &c2);
void display()
{
if (imag>0)
cout<<real<<'+'<<imag<<'i'<<endl;
else
cout<<real<<imag<<'i'<<endl;
}
//类的友元函数可以调用类内的成员,所以可以将类的数据成员定义为私有的
private:
float real;
float imag;
};
//类的友元函数不属于任何一个类,所以直接定义即可,不要加作用域符号
Complex operator/(Complex &c1,Complex &c2)
{
Complex c;
c.real=(c1.real*c2.real-c1.imag*c2.imag)/(c2.real*c2.real-c2.imag*c2.imag);
c.imag=(c1.real*c2.imag+c2.real*c1.imag)/(c2.real*c2.real-c2.imag*c2.imag);
return c;
}
int main()
{
Complex complex1(1,2),complex2(3,4),complex;
cout<<"complex1="; complex1.display();
cout<<"complex2="; complex2.display();
complex=complex1/complex2;
cout<<"complex=";
complex.display();
return 0;
}