c++ - 我怎样才能简化这个程序?
问题描述
我正在编写一个程序,该程序使用异常处理来查找二次方程的根,我想知道是否有一种方法可以简化程序,我有一堆用于 catch 案例的空类
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
class all_zero{
};
class negative{
};
class zero_division{
};
void roots(double a, double b, double c) throw (all_zero,negative,zero_division);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
cout << "Enter the three coefficients \n";
cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(all_zero) {cout << "All values are zero \n";}
catch(negative) {cout << "Square root of negative values is not defined \n";}
catch(zero_division) {cout << "Division by zero, not defined \n";}
return 0;
}
void roots(double a, double b, double c) throw (all_zero,negative,zero_division){
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
cout << "The two roots are: "<< x1 <<" and " << x2 << endl;
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
有没有办法可以做到,所以我没有空类或将它们放入结构的方法?
解决方案
请注意,您使用的动态异常规范在 C++11 中已弃用,并在 C++17 中删除:
void roots(double a, double b, double c) throw (all_zero,negative,zero_division)
// ^^
你可以删除它。
using namespace std;
被认为是不好的做法。
不要std::endl
用于添加换行符。std::endl
添加一个新行并刷新流。大多数时候这是不必要的。用于'\n'
添加换行符。
有没有办法可以做到,所以我没有空类或将它们放入结构的方法?
实际上,我认为为不同类型的异常设置单独的类并没有什么坏处。您的方法的缺点是“什么”在 中catch
,而不是异常的一部分或来自异常发生的地方。我将向您展示第一个(消息是类型的一部分),并希望您能看到如何实现后者(消息来自引发异常的位置)。
您可以继承std::runtime_error
which 提供的what()
方法,该方法返回传递给构造函数的字符串。这也使其他人更容易捕获您的异常,因为std::runtime_error
反过来继承自std::excpetion
which 是所有标准异常的基类:
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <stdexcept>
struct all_zero : std::runtime_error {
all_zero() : std::runtime_error("All values are zero") {}
};
struct negative : std::runtime_error {
negative() : std::runtime_error("Square root of negative values is not defined") {}
};
struct zero_division : std::runtime_error {
zero_division() : std::runtime_error("Division by zero, not defined") {}
};
void roots(double a, double b, double c);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
std::cout << "Enter the three coefficients \n";
std::cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(std::runtime_error& ex) {std::cout << ex.what() << '\n';}
return 0;
}
void roots(double a, double b, double c) {
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
std::cout << "The two roots are: "<< x1 <<" and " << x2 << "\n";
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
注意异常应该作为引用被捕获,否则在导出异常时会有对象切片。通常你不知道你会捕获什么类型的异常,你需要小心避免这种情况。
或者,您可以使用更通用的异常类型(roots_exception
?),而不是硬编码“什么”,然后将它传递给构造函数throw
。
您可能还有更多可以改进的地方,为此我建议您https://codereview.stackexchange.com/。
PS:我试图将样式放在一边,尽管您应该更改的另一件事是从函数返回结果,而不是仅仅将其打印到屏幕上。如果您想将结果用于目前无法进行的其他计算。也许您对如何返回两个值感到困惑。std::pair
很简单:
std::pair<double,double> roots(...) {
// ...
return {x1,x2};
}
接着:
try {
auto result = roots(a,b,c);
std::cout << "The two roots are: "<< result.first <<" and " << result.second << "\n";
}
推荐阅读
- flutter - Dart 版本更改
- python - 按索引减去两个数据帧并保留字符串列
- react-admin - 从 useListContext 构建 url?
- r - 替换第一个括号和之间的文本。无需卸下支架和
- excel - 如何根据每列自己的值将条件格式应用于多列
- reactjs - React 函数组件中的多个 useLazyQuery 钩子(Apollo 客户端)
- vuex - VUE 3 JS:无法访问我的已安装道具
- python - “ImportError:没有名为六个的模块”ubuntu 20.04
- python - 有没有办法通过指定功能而不是严重性来使用 Python 中的日志记录?
- django - 如何使用 .local 域运行带有 SSL 的本地 Django 开发服务器?