题目:成运算符重载员函数形式实现复数类的四则运算
|
class Complex double real,imag; public: Complex(){real=0; imag=0;} Complex(double r, double i){ real=r; imag=r;} double getreal(); double getimag(); void setreal(double r); void setimag(double i); double display(); }; |
OK,到这里我们先对这个要求进行实现:
首先按照题目给的要求进行头文件的声明,我们需要加上运算符重载函数的声明,C++语法规定重载运算符函数的一般格式为将其重载为成员函数的类型:
T operator @(参数表){
重载函数体
}
//其中T为返回类型,但是一般所操作的类的类型相同,所以通常情况下我们直接用类名,operator为关键字,@为运算符名称,参数表为参与运算的数据即操作数;
//因为是在类中定义的操作,操作的一方就是当前的对象, 成员变量可以随意访问,这样的话,只要设置一个参数作为右侧操作数,而左侧运算量就是该对象本身;如果是单目运算符,就不必另外设置参数,运算符的操作量就是该对象本身。
但这只是其中一种,还有另外一种将其重载为友元函数的形式:
friend 返回类型 operator @(参数表){
//函数体
}
//同上
//事实上,友元重载函数定义在类体外,作为该类的友元函数,访问其私有成员,但却降低了该类的独立性,破坏了该类的封装特性
//在第一个参数需要隐式转换的情形下,使用友元函数函数重载运算符是正确的选择,这是因为友元函数没有隐含的this指针,用友元函数重载运算符时,所需操作数必须在参数表显式声明,所以很容易实现类型的隐式转换。
//如果运算符的操作数需要修改对象状态时,则 它应该是友元函数,而需要左值操作数的运算符,如=,*=,++应该用成员函数。
//运算符=、()、[]、->不能用友元函数重载。
我们来具体实现题目中的要求:
第一种:重载为成员函数
//Complex.h
#include
using namespace std;
class Complex{ //复数类
private:
double real, image;
public:
Complex(){ real = 0; image = 0; }
Complex(double r, double i){ real = r; image = i; }
double getreal();
double getimage();
void setreal(double r);
void setimage(double i);
double display();
Complex operator+(const Complex &c); //加法操作,双目
Complex operator-(const Complex &c); //减法操作,双目
Complex operator*(const Complex &c); //乘法操作,双目
Complex operator/(const Complex &c); //除法操作,双目
};
第二种方式:重载为友元函数
//created by kong at 2019-11-02
//友元Complex.h
#include
using namespace std;
class Complex{ //复数类
private:
double real, image;
public:
Complex(){ real = 0; image = 0; }
Complex(double r, double i){ real = r; image = i; }
double getreal();
double getimage();
void setreal(double r);
void setimage(double i);
double display();
friend Complex operator+(const Complex &c1, const Complex &c2); //加法操作,双目
friend Complex operator-(const Complex &c1, const Complex &c2); //减法操作,双目
friend Complex operator*(const Complex &c1, const Complex &c2); //乘法操作,双目
friend Complex operator/(const Complex &c1, const Complex &c2); //除法操作,双目
};
那么具体的实现上两种凡是有什么不同呢?
首先是重载为成员函数的定义:
//Complex.cpp
#include
#include"Complex.h"
using namespace std;
double Complex::getreal(){
if (real!=0) cout << real << endl;
return 0;
}
double Complex::getimage(){
if (image != 0) cout << image << "i"<0)
cout << real << "+" << image << "i" << endl;
else if (image<0)
cout << real << image << "i" << endl;
return 0;
}
Complex Complex::operator+(const Complex &c){
Complex temp(real + c.real, image + c.image);
return temp;
}
Complex Complex::operator-(const Complex &c){
Complex temp(real - c.real, image - c.image);
return temp;
}
Complex Complex::operator*(const Complex &c){
Complex temp(real * c.real, image * c.image);
return temp;
}
Complex Complex::operator/(const Complex &c){
Complex temp(real / c.real, image / c.image);
return temp;
}
友元重载函数的定义:
//友元Complex.cpp
#include
#include"Complex.h"
using namespace std;
double Complex::getreal(){ //获取复数实部
if (real!=0)
cout << real << endl;
return 0;
}
double Complex::getimage(){ //获取复数虚部
if (image != 0)
cout << image << "i"<0)
cout << real << "+" << image << "i" << endl;
else if (image<0)
cout << real << image << "i" << endl;
return 0;
Complex operator+(const Complex &c1, const Complex &c2){
Complex temp(c1.real + c2.real, c1.image + c2.image);
return temp;
}
Complex operator-(const Complex &c1, const Complex &c2){
Complex temp(c1.real - c2.real, c1.image - c2.image);
return temp;
}
Complex operator*(const Complex &c1, const Complex &c2){
Complex temp(c1.real * c2.real, c1.image * c2.image);
return temp;
}
Complex operator/(const Complex &c1, const Complex &c2){
Complex temp(c1.real / c2.real, c1.image / c2.image);
return temp;
}
我们能看到只要重载函数上的实现不同,而对于他们的主测试函数如下:
#include
#include"Complex.h"
using namespace std;
int main(){
Complex c1(2, 3),c2(4,4),c3;
c1.getreal();
c2.getimage();
c3 = c1 + c2;
c3.display();
c3 = c1 - c2;
c3.display();
c3 = c1 * c2;
c3.display();
c3 = c1 / c2;
c3.display();
return 0;
}
运行结果为:
至此我们已经完成了这个函数的全部代码编写,那么我们来看下剩下的问题
1.以成员函数实现的复数加法运算为什么不能支持加法的交换律?
答:表达式z=z+27编译器解释为z.operator+(27),是合法的,但是对表达式z=27+z来说,解释为27.operator(z)是没有意义的,因为27不是不是类类型对象,不能调用运算符重载函数。
2.如果必须支持复数加法运算支持交换律,你会采用哪种形式编程实现?
答:可选择再重载一次+运算符,函数形式如下
Complex operator+(int I, Complex &c){
return Complex(c.real+i, c.image);
}