C++程序设计 上机实验(第10章——运算符重载)

1. 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和

#include <iostream>
using namespace std;
class Complex 
{
public:
    Complex() { real = 0; image = 0; }
    Complex(double r, double i) { real = r, image = i; }
    double get_real(); //声明get_real函数
    double get_image(); //声明get_image函数
    void display();
private:
    double real;
    double image;
};

double Complex::get_real() //取数据成员real(实部)的值
{return real; }
double Complex::get_image() //取数据成员image(虚部)的值
{ return image; }

void Complex::display() 
{ cout << "(" << real << "," << image << "i)" << endl; }

Complex operator+(Complex& c1, Complex& c2) 
{ return Complex(c1.get_real() + c2.get_real(), c1.get_image() + c2.get_image()); }


int main() {
    Complex c1(3, 4), c2(5, -10), c3;
    c3 = c1 + c2;
    cout << "c3=";
    c3.display();
    return 0;
}

//运行结果:c3=(8,-6i)

程序分析:

  • 运算符重载函数既不是类Complex的成员函数,也不是类Complex的友元函数,而是一个普通函数。
  • 由于运算符重载函数operator+是非成员和非友元的普通函数,因此它不能直接引用Complex类中的私有成员
    结论:一般不把运算符函数重载为非成员和非友元的普通函数

2. 定义一个复数类Complex,重载运算符"+","-","*","/",使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数。编写程序,分别求两个复数之和、查、积和商

如果有两个复数:m=a+bi,n=c+di。复数的加、减、乘、除的公式如下:

  • 复数加法: m + n = a + b i + c + d i = ( a + c ) + ( b + d ) i m+n=a+bi+c+di=(a+c)+(b+d)i m+n=a+bi+c+di=(a+c)+(b+d)i
  • 复数减法: m − n = a + b i − c − d i = ( a − c ) + ( b − d ) i m-n=a+bi-c-di=(a-c)+(b-d)i mn=a+bicdi=(ac)+(bd)i
  • 复数乘法: m × n = ( a + b i ) ( c + d i ) = a c + b c i + a d i + b d i ² = ( a c − b d ) + ( b c + a d ) i m×n=(a+bi)(c+di)=ac+bci+adi+bdi²=(ac-bd)+(bc+ad)i m×n=(a+bi)(c+di)=ac+bci+adi+bdi²=(acbd)+(bc+ad)i
  • 复数除法: m n = ( a + b i ) ( c − d i ) ( c + d i ) ( c − d i ) = a c + b c i − a d i − b d i ² c ² + d ² = ( a c + b d ) + ( b c − a d ) i c ² + d ² = a c + b d c ² + d ² + b c − a d c ² + d ² i \frac{m}{n}=\frac{(a+bi)(c-di)}{(c+di)(c-di)}=\frac{ac+bci-adi-bdi²}{c²+d²}=\frac{(ac+bd)+(bc-ad)i}{c²+d²}=\frac{ac+bd}{c²+d²}+\frac{bc-ad}{c²+d²}i nm=(c+di)(cdi)(a+bi)(cdi)=c²+d²ac+bciadibdi²=c²+d²(ac+bd)+(bcad)i=c²+d²ac+bd+c²+d²bcadi
#include<iostream>
using namespace std;
class Complex
{
public:
	Complex() { real = 0; imag = 0; }
	Complex(double r, double i) { real = r; imag = i; }
	Complex operator+(Complex& c2);
	Complex operator-(Complex& c2);
	Complex operator*(Complex& c2);
	Complex operator/(Complex& c2);
	void display();
private:
	double real;
	double imag;
};

Complex Complex::operator+(Complex& c2) //重载运算符"+"
{
	Complex c;
	c.real = real + c2.real; //计算实部
	c.imag = imag + c2.imag; //计算虚部
	return c;
}

Complex Complex::operator-(Complex& c2) //重载运算符"-"
{
	Complex c;
	c.real = real - c2.real; //计算实部
	c.imag = imag - c2.imag; //计算虚部
	return c;
}

Complex Complex::operator*(Complex& c2) //重载运算符"*"
{
	Complex c;
	c.real = real * c2.real - imag * c2.imag; //计算实部
	c.imag = imag * c2.real + real * c2.imag; //计算虚部
	return c;
}

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 = (imag * c2.real - real * c2.imag) / (c2.real * c2.real + c2.imag * c2.imag); //计算虚部
	return c;
}

void Complex::display()
{
	cout << "(" << real << "," << imag << "i)" << endl; //输出复数
}

int main()
{
	Complex c1(3, 4), c2(5, -10), c3;
	c3 = c1 + c2;
	cout << "c1+c2=";
	c3.display();

	c3 = c1 - c2;
	cout << "c1+c2=";
	c3.display();

	c3 = c1 * c2;
	cout << "c1*c2=";
	c3.display();

	c3 = c1 / c2;
	cout << "c1/c2=";
	c3.display();
	return 0;
}

运行结果:

3. 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算。参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意。编写程序,分别求出两个复数之和、整数和复数之和

#include<iostream>
using namespace std;
class Complex
{
public:
	Complex() { real = 0; imag = 0; }
	Complex(double r, double i) { real = r; imag = i; }
	Complex operator+(Complex& c2); //运算符重载为成员函数
	Complex operator+(int& i); //运算符重载为成员函数
	friend Complex operator+(int&, Complex&); //运算符重载为友元函数
	void display();
private:
	double real;
	double imag;
};

Complex Complex::operator+(Complex& c) //定义成员运算符函数
{
	return Complex(real + c.real, imag + c.imag);
}


Complex Complex::operator+(int& i) //定义成员运算符函数
{
	return Complex(real + i, imag);
}

void Complex::display()
{
	cout << "(" << real << "," << imag << "i)" << endl; //输出复数
}

Complex operator+(int& i, Complex & c)
{
	return Complex(i + c.real, c.imag);
}

int main()
{
	Complex c1(3, 4), c2(5, -10), c3;
	int i = 5;
	c3 = c1 + c2;
	cout << "c1+c2=";
	c3.display();

	c3 = i + c1;;
	cout << "i+c1=";
	c3.display();

	c3 = c1 + i;
	cout << "c1+i=";
	c3.display();
	return 0;
}

程序分析:

  • 由于前两个重载函数的第一个参数为类对象,所以将它们作为类的成员函数,函数的第一个参数也可以省略。第3个重载函数的第一个参数为int型,不是类对象,不能作为类的成员函数,只能作为友元函数,函数的两个参数不能省略。
  • 也可以将以上3个运算符函数都重载为友元函数,这时3个运算符函数都有两个参数,不能省略。注意在友元函数中引用数据成员必须用对象名。

运行结果:

4. 有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符"+",使之能用于两个矩阵相加。

#include<iostream>
using namespace std;
class Matrix
{
public:
	Matrix(); //默认构造函数
	friend Matrix operator+(Matrix&, Matrix&); //重载运算符"+"
	void input(); //输入数据函数
	void display(); //输出数据函数
private:
	int mat[2][3];
};

Matrix::Matrix() //定义构造函数
{
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			mat[i][j] = 0;
}

Matrix operator+(Matrix& a, Matrix& b) //定义重载运算符+函数
{
	Matrix c;
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			c.mat[i][j] = a.mat[i][j] + b.mat[i][j];
	return c;
}

void Matrix::input() //定义输入数据函数
{
	cout << "input value of matrix:";
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			cin >> mat[i][j];
}

void Matrix::display()
{
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << mat[i][j] << " ";
		}
		cout << endl;
		}
}

int main()
{
	Matrix a, b, c;
	a.input();
	b.input();
	cout << endl << "Matrix a:" << endl;
	a.display();
	cout << endl << "Matrix b:" << endl;
	b.display();
	c = a + b;
	cout << endl << "Matrix c = Matrix a + Marix b:" << endl;
	c.display();
	return 0;
}

运行结果:

5. 在上题的基础上,重载流插入运算符"<<“和流提取运算符”>>",使之能用于该矩阵的输入和输出

#include<iostream>
using namespace std;
class Matrix
{
public:
	Matrix(); //默认构造函数
	friend Matrix operator+(Matrix&, Matrix&); //重载运算符"+"的函数声明
	friend ostream& operator<<(ostream&, Matrix&); //重载运算符"<<"的函数声明
	friend istream& operator>>(istream&, Matrix&); //重载运算符">>"的函数声明
private:
	int mat[2][3];
};

Matrix::Matrix() //定义构造函数
{
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			mat[i][j] = 0;
}

Matrix operator+(Matrix& a, Matrix& b) //定义运算符"+"的重载函数
{
	Matrix c;
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			c.mat[i][j] = a.mat[i][j] + b.mat[i][j];
	return c;
}

istream& operator>>(istream& in, Matrix& m)
{
	cout << "input value of matrix:";
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 3; j++)
			in >> m.mat[i][j];
	return in;
}

ostream& operator<<(ostream& out, Matrix& m)
{
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			out<< m.mat[i][j]<<" ";
		}
		out << endl;
	}
	return out;
}

int main()
{
	Matrix a, b, c;
	cin >> a;
	cin >> b;
	cout << endl << "Matrix a:" << endl << a << endl;
	cout << endl << "Matrix b:" << endl << b << endl;
	c = a + b;
	cout << endl << "Matrix c = Matrix a + Marix b:" << endl << c << endl;
	return 0;
}

6. 请编写程序,处理一个复数域一个double数相加的运算,结果存放在一个double型的变量d1中,输出d1的值,再以复数形式输出此值。定义Complex(复数)类,在成员函数中包含重载类型转换运算符:operator double(){return real;}

#include<iostream>
using namespace std;
class Complex
{
public:
	Complex() { real = 0; imag = 0; } //默认构造函数,无形参
	Complex(double r) { real = r; imag = 0; } //转换构造函数,一个形参
	Complex(double r, double i) { real = r; imag = i; } //实现初始化的构造函数,两个形参
	operator double() { return real; } //重载类型转换运算符
	void display();
private:
	double real;
	double imag;
};

void Complex::display()
{
	cout << "(" << real << "," << imag << ")" << endl;
}

int main()
{
	Complex c1(3, 4), c2;
	double d1;
	d1 = 2.5 + c1; //将c1转换为double型数,与2.5相加,结果为double型数
	cout << "d1=" << d1 << endl; //输出double型变量d1的值
	c2 = Complex(d1); //将d1再转换为复数
	cout << "c2=";
	c2.display(); //输出复数c2
	return 0;
}

//运行结果:
d1=5.5
c2=(5.5,0)

程序分析:

  • 在处理表达式"2.5+c1"时,由于二者的类型不同,如果没有重载强制类型转换运算符,二者是不能相加的。由于在Complex类中已重载了类型转换运算符double,在程序编译时,编译系统找到了此函数,并将Complex类对象c1(复数)转换成一个double型数据3.0,然后将2.5与3.0相加,得5.5。用cout语句输出d1的值。
  • 如果想将d1以复数形式表示,可以利用转换构造函数将d1转换为Complex类对象,即Complex(d1)。主函数最后两行就是为了处理这个问题。

如果将程序中的Complex类的公用部分改为:

class Complex
{
public:
	Complex() { real = 0; imag = 0; }
	Complex(double r) { real = r; imag = 0; } //转换构造函数
	Complex(double r, double i) { real = r; imag = i; }
	operator double() { return real; } //重载类型转换运算符
	friend Complex operator+(Complex c1, Complex c2);
	void display();
private:
	double real;
	double imag;
};

程序分析:

  • 如果想把"2.5+c1"处理为两个复数相加,而不是按两个double数相加,程序在编译时出错,原因是出现二义性。一种理解是:调用转换构造函数,把2.5变成Complex类对象,然后调用运算符"+“重载函数,与c1进行复数相加。另一种理解是:调用类型转换函数,把c1转换为double型数,然后与2.5进行相加。系统无法判定,这二者是矛盾的。如果要使用类型转换函数,就应当删去运算符”+"重载函数。
  • 转换构造函数是将double型数据转化为Complex类对象,类型转换函数是将Complex类对象转换成一个double型数据。

7. 定义一个Teacher(教师)类和一个Student(学生)类,二者有一部分数据成员是相同的,例如num(号码),name(姓名),sex(性别)。编写程序,将一个Student对象(学生)转换为Teacher(教师)类,只将以上3个相同的数据成员移植过去。可以设想为:一位学生大学毕业了,留校担任教师,他原有的部分数据对现在的教师身份来说仍然是有用的,应当保留并成为其教师数据的一部分。

#include<iostream>
using namespace std;
class Student //定义学生类
{
public:
	Student(int, char[], char, float); //构造函数声明
	int get_num() { return num; } //返回num的值
	char* get_name() { return name; } //返回name的值
	char get_sex() { return sex; } //返回sex的值
	void display()
	{
		cout << "num:" << num << "\nname:" << name << "\nsex:" << sex << "\nscore:" << score << "\n\n";
	}
private:
	int num;
	char name[20];
	char sex;
	float score; //成绩
};

Student::Student(int n, char nam[], char s, float sco) //定义Student构造函数
{
	num = n;
	strcpy(name, nam);
	sex = s;
	score = sco;
};

class Teacher //定义教师类
{
public:
	Teacher(){} //默认构造函数
	Teacher(Student&); //转换构造函数
	Teacher(int n, char nam[], char sex, float pay); //构造函数重载
	void display(); 
private:
	int num;
	char name[20];
	char sex;
	float pay; //工资
};

Teacher::Teacher(int n, char nam[], char s, float p) //定义Teacher构造函数
{
	num = n;
	strcpy(name, nam);
	sex = s;
	pay = p;
}

Teacher::Teacher(Student& stud) //定义转换构造函数
{
	num = stud.get_num(); //将Student类对象的num成员转换为Teacher类对象的num
	strcpy(name, stud.get_name());
	sex = stud.get_sex();
	pay = 1500; //假定试用期临时工资一律为1500元
}

void Teacher::display()
{
	cout<<"num:" << num << "\nname:" << name << "\nsex:" << sex << "\npay:" << pay << "\n\n";
}

int main()
{
	Teacher teacher1(10001, "Li", 'f', 1234.5), teacher2;
	Student student1(20010, "Wang", 'm', 89.5);
	cout << "student1:" << endl;
	student1.display(); //输出学生student1的信息
	teacher2 = Teacher(student1); //将student1转换为Teacher类
	cout << "teacher2:" << endl;
	teacher2.display(); //输出教师teacher2的信息
	return 0;
}

运行结果

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值