网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元

第9单元 - 作业4:OJ编程 - 使用自定义异常类处理复数运算的错误

�返回
 

温馨提示:

1.本次作业属于Online Judge题目,提交后由系统即时判分。

2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩。

自定义异常类处理复数运算的错误

依照学术诚信条款,我保证此作业是本人独立完成的。

1
在作业3的基础上,修改相关代码。创建一个自定义的异常类,并且使用这个类来处理复数除法中除数为0的异常(5分)
时间限制:500ms内存限制:32000kb
 
#include <iostream>
#include <exception>
#include <stdexcept>
#include <limits>
#include <cmath>

using namespace std;

class MyComplex//2. 创建一个类 MyComplex,用来表示复数。
{
public:
	MyComplex();
	MyComplex(double a, double b);

	friend ostream& operator <<(ostream& os, const MyComplex& z);//4. 重载流插入运算符 << ,使之可以将复数输出为如下的格式(实部如果是非负数,则不输出符号位;输出时要包含半角左右小括号):
	friend istream& operator >> (istream& is, MyComplex& z);//3. 重载流提取运算符 >> ,使之可以读入以下格式的输入(两个数值之间使用空白分隔),将第一个数值存为复数的实部,将第二个数值存为复数的虚部:

	MyComplex operator+(const MyComplex &secondMyComplex);//加法法则:(a+bi)+(c+di)=(a+c)+(b+d)i;
	MyComplex operator-(const MyComplex &secondMyComplex);//减法法则:(a+bi)-(c+di)=(a-c)+(b-d)i;
	MyComplex operator*(const MyComplex &secondMyComplex);//乘法法则:(a+bi)·(c+di)=(ac-bd)+(bc+ad)i;
	MyComplex operator/(const MyComplex &secondMyComplex);//除法法则:(a+bi)÷(c+di)=[(ac+bd)/(c²+d²)]+[(bc-ad)/(c²+d²)]i.

private:
	double a_;
	double b_;
};

class DivisionException :public runtime_error
{
	//1. 在作业3的基础上,修改相关代码。创建一个自定义的异常类,并且使用这个类来处理复数除法中除数为0的异常
	//2. 类的名字为 DivisionException,继承自 runtime_error(需包含头文件 <stdexcept>)
public:
	//5. DivisionException 有一个显式定义的构造函数。该构造函数接受3个参数。
	//5.1 参数1:类型为字符串,其中保存着对异常的描述信息(message),该字符串需传递给其直接基类(runtime_error)的构造函数;最后可以通过DivisionException类从其基类继承下来的 what() 函数读出该信息(message)
	//5.2 参数2:发生异常的复数除法中的被除数;构造函数将参数2的值存入类的数据成员中
	//5.3 参数3:发生异常的复数除法中的除数。构造函数将参数3的值存入类的数据成员中
	DivisionException(string message, MyComplex divident, MyComplex divisor);
	MyComplex getDivident();//4. DivisionException 中应包含两个MyComplex类型的数据成员的getter函数。函数形式参见本作业后面所给的主函数。
	MyComplex getDivisor();//4. DivisionException 中应包含两个MyComplex类型的数据成员的getter函数。函数形式参见本作业后面所给的主函数。

private:
	MyComplex divident_;//3. DivisionException 中有两个MyComplex类型的数据成员,分别保存出现异常时的被除数和除数
	MyComplex divisor_;
};

MyComplex::MyComplex()
{
}

MyComplex::MyComplex(double a, double b)
{
	a_ = a;
	b_ = b;
}

ostream & operator<<(ostream & os, const MyComplex & z)//4. 重载流插入运算符 << ,使之可以将复数输出为如下的格式(实部如果是非负数,则不输出符号位;输出时要包含半角左右小括号):
{
	// TODO: 在此处插入 return 语句
	os.unsetf(std::ios::showpos);

	os << "(" << z.a_;

	os.setf(std::ios::showpos);

	os << z.b_ << "i)";

	return os;
}

istream & operator >> (istream & is, MyComplex & z)//3. 重载流提取运算符 >> ,使之可以读入以下格式的输入(两个数值之间使用空白分隔),将第一个数值存为复数的实部,将第二个数值存为复数的虚部:
{
	// TODO: 在此处插入 return 语句
	is >> z.a_ >> z.b_;
	return is;
}

MyComplex MyComplex::operator+(const MyComplex & secondMyComplex)//加法法则:(a+bi)+(c+di)=(a+c)+(b+d)i;
{
	return MyComplex(a_ + secondMyComplex.a_, b_ + secondMyComplex.b_);
}

MyComplex MyComplex::operator-(const MyComplex & secondMyComplex)//减法法则:(a+bi)-(c+di)=(a-c)+(b-d)i;
{
	return MyComplex(a_ - secondMyComplex.a_, b_ - secondMyComplex.b_);
}

MyComplex MyComplex::operator*(const MyComplex & secondMyComplex)//乘法法则:(a+bi)·(c+di)=(ac-bd)+(bc+ad)i;
{
	return MyComplex(a_ * secondMyComplex.a_ - b_ * secondMyComplex.b_, secondMyComplex.a_ * b_ + a_ * secondMyComplex.b_);
}

MyComplex MyComplex::operator/(const MyComplex & secondMyComplex)//除法法则:(a+bi)÷(c+di)=[(ac+bd)/(c²+d²)]+[(bc-ad)/(c²+d²)]i.
{
	//6. 在MyComplex类中对除法运算符重载的代码中,当除数为0时,抛出的一个 DivisionException类型的异常对象。在构造该异常对象时,其构造函数的第一个参数的字符串内容是“Divisor is 0”(不包含双引号,单词(数字)之间有一个空格字符。)

	if (pow(secondMyComplex.a_, 2) + pow(secondMyComplex.b_, 2) == 0)//2. 在做除法时,如果除数是0,则输出一条信息:“Divisor can not be 0” (注意:请精确复制这段信息,否则即便你的程序逻辑正确,OJ系统仍然会判你失败。输出信息中不包含引号)然后结束程序(调用 exit() 函数),直接退出(注意,传递给操作系统的返回值与main函数正常结束时相同,仍然为0)。
	{
		throw DivisionException("Divisor is 0", MyComplex(a_, b_), MyComplex(secondMyComplex.a_, secondMyComplex.b_));
	}

	return MyComplex((a_ * secondMyComplex.a_ + b_ * secondMyComplex.b_) / (pow(secondMyComplex.a_, 2) + pow(secondMyComplex.b_, 2)), (b_ * secondMyComplex.a_ - a_ * secondMyComplex.b_) / (pow(secondMyComplex.a_, 2) + pow(secondMyComplex.b_, 2)));
}

DivisionException::DivisionException(string message, MyComplex divident, MyComplex divisor) :runtime_error(message)
{
	divident_ = divident;
	divisor_ = divisor;
}

MyComplex DivisionException::getDivident()//4. DivisionException 中应包含两个MyComplex类型的数据成员的getter函数。函数形式参见本作业后面所给的主函数。
{
	return divident_;
}

MyComplex DivisionException::getDivisor()//4. DivisionException 中应包含两个MyComplex类型的数据成员的getter函数。函数形式参见本作业后面所给的主函数。
{
	return divisor_;
}

int main() {
	MyComplex z1, z2;
	cin >> z1;
	cin >> z2;
	try {
		cout << "z1 + z2 = " << z1 + z2 << endl;
		cout << "z1 - z2 + z1 = " << z1 - z2 + z1 << endl;
		cout << "z1 * z2 - z1 = " << z1 * z2 - z1 << endl;
		cout << "z1 / z2 + z1 = " << z1 / z2 + z1 << endl;
		cout << "z2 - z1 / z1 = " << z2 - z1 / z1 << endl;
		cout << "Finished";
	}
	catch (DivisionException& e) {
		cout << e.what() << ": " << e.getDivident() << "/" << e.getDivisor() << endl;
		cout << "Unexpected Error";
	}

	// GCC及VC编译器在调试模式下会暂停,便于查看运行结果
#if ( defined(__DEBUG__) || defined(_DEBUG) )
	cin.ignore(numeric_limits<streamsize>::max(), '
');
	cin.get();
#endif
	return 0;
}
原文地址:https://www.cnblogs.com/denggelin/p/7137091.html