C++编程入门--运算符重载复数类

题目:成运算符重载员函数形式实现复数类的四则运算

  • 上机指导2中,我们以独立函数形式(非成员函数,非友元函数)实现了Complex附属类的加减乘除四则运算,这里要求用Complex成员函数形式实现Complex对象的加减乘除运算。
  • Complex类的基本定义形式如下(仅供参考)

 

  1.  
  2.  
  3.  
  4.    

class Complex
{
   private:

      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();

};

  • Complex类的“+”、“-”、“*”、“/”成员函数重载的声明,以及各成员数的实现。
  • 请编写测试用的主函数,测试你所定义的“+”、“-”、“*”、“/”运算符重载形式是否正确。

OK,到这里我们先对这个要求进行实现:

首先按照题目给的要求进行头文件的声明,我们需要加上运算符重载函数的声明,C++语法规定重载运算符函数的一般格式为将其重载为成员函数的类型:

T operator @(参数表){

重载函数体

}

//其中T为返回类型,但是一般所操作的类的类型相同,所以通常情况下我们直接用类名,operator为关键字,@为运算符名称,参数表为参与运算的数据即操作数;

//因为是在类中定义的操作,操作的一方就是当前的对象, 成员变量可以随意访问,这样的话,只要设置一个参数作为右侧操作数,而左侧运算量就是该对象本身;如果是单目运算符,就不必另外设置参数,运算符的操作量就是该对象本身。

但这只是其中一种,还有另外一种将其重载为友元函数的形式:

friend 返回类型 operator @(参数表){

//函数体

}

//同上

//事实上,友元重载函数定义在类体外,作为该类的友元函数,访问其私有成员,但却降低了该类的独立性,破坏了该类的封装特性

//在第一个参数需要隐式转换的情形下,使用友元函数函数重载运算符是正确的选择,这是因为友元函数没有隐含的this指针,用友元函数重载运算符时,所需操作数必须在参数表显式声明,所以很容易实现类型的隐式转换。

//如果运算符的操作数需要修改对象状态时,则 它应该是友元函数,而需要左值操作数的运算符,如=,*=,++应该用成员函数。

//运算符=、()、[]、->不能用友元函数重载。

我们来具体实现题目中的要求:

第一种:重载为成员函数

//Complex.h
#include<iostream>
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<iostream>
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<iostream>
#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"<<endl;
	return 0;
}
void Complex::setreal(double r){
	real = r;
}
void Complex::setimage(double i){
	image = i;
}
double Complex::display(){      //输出格式:a+bi或a-bi
	if (image>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<iostream>
#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"<<endl;
	return 0;
}
void Complex::setreal(double r){   //设置复数实部
	real = r;
}
void Complex::setimage(double i){  //设置复数虚部
	image = i;
}
double Complex::display(){      //输出格式:a+bi或a-bi
	if (image>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<iostream>
#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;
}

运行结果为:

至此我们已经完成了这个函数的全部代码编写,那么我们来看下剩下的问题

  • 下面请尝试在你的主函数中添加如下的测试语句段:
     Complex  z ( 2 , 3 ) ;
     z = z + 27 ;          //  正确
     z = 27 + z ;            //  错误语句
    请回答以下的问题:

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);

}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值