【发布时间】:2021-11-26 14:39:36
【问题描述】:
这是导致错误的 v1
#include <iostream>
#include "exceptionHandlingV2.h"
using namespace std;
int main() {
exceptionHandlingV2 ob(4,0);
cout<<ob.divide();
cout<<"\nbye";
return 0;
}
#ifndef EXCEPTION_HANDLING_V2_EXCEPTIONHANDLINGV2_H
#define EXCEPTION_HANDLING_V2_EXCEPTIONHANDLINGV2_H
#include <iostream>
using namespace std;
class exceptionHandlingV2 {
private:
int numerator;
int denominator;
string error;
public:
exceptionHandlingV2();
exceptionHandlingV2(int ,int);
void setDenominator(int );
void setNumerator(int );
void readAgain ();
void print_errors();
double divide() const;
};
#endif //EXCEPTION_HANDLING_V2_EXCEPTIONHANDLINGV2_H
#include "exceptionHandlingV2.h"
exceptionHandlingV2::exceptionHandlingV2(){
numerator=1;
denominator=1;
}
exceptionHandlingV2::exceptionHandlingV2(int numerator,int denominator){
setNumerator(numerator);
try {
setDenominator(denominator);
error = "";
}catch (const char * e){
error = e;
print_errors();
readAgain();
}
}
void exceptionHandlingV2::setDenominator(int denominator){
if ( denominator == 0 ){
throw "divided by zero\n";
}
(*this).denominator = denominator;
}
void exceptionHandlingV2::readAgain (){
int temp;
cout<<"enter denominator again other than 0\n";
cin >> temp;
exceptionHandlingV2 ( numerator,temp );
}
void exceptionHandlingV2::print_errors(){
cout<<error;
}
void exceptionHandlingV2::setNumerator(int numerator){
(*this).numerator = numerator;
}
double exceptionHandlingV2::divide() const{
return (double)numerator/denominator;
}
这是我在构造函数中停止与用户交互的 v2 设计
exceptionHandlingV2::exceptionHandlingV2(int numerator,int denominator){
setNumerator(numerator);
setDenominator( denominator );
}
void exceptionHandlingV2::setDenominator(int denominator){
try
{
if ( denominator == 0 )
throw "divided by zero\n";
(*this).denominator = denominator;
error = "";
}
catch (const char * e)
{
error = e;
print_errors();
readAgain();
}
}
在 v3 设计中,我添加了一个新函数来处理类本身的异常
exceptionHandlingV4::exceptionHandlingV4(int numerator,int denominator){
setNumerator(numerator);
setDenominator( denominator );
}
void exceptionHandlingV4::setDenominator(int denominator){
try {
runtime_set_denominator_error ( denominator );
}
catch ( const char *e )
{
error = e;
print_errors();
readAgain();
}
}
void exceptionHandlingV4 :: runtime_set_denominator_error ( int denominator ){
if ( !denominator )
throw "divided by zero \n";
(*this).denominator = denominator;
error = "";
}
我做了一个 v4 设计来停止在类中处理异常,而不是在 main() 中进行。哪一个是正确的?在类中处理异常或只是从类中抛出异常并在 main 中处理?问题是我不能再继续从用户读取 readAgain() 直到用户输入写入输入,因为异常将进入 catch 块并且无法处理catch 块中的运行时错误,所以我从设计中删除了 readagain() 函数,只在 main() 部分打印了错误
exceptionHandlingV5::exceptionHandlingV5(int numerator,int denominator){
setNumerator(numerator);
setDenominator( denominator );
}
void exceptionHandlingV5::setDenominator(int denominator){
if ( !denominator ){
error = "divided by zero \n";
throw "divided by zero\n";
}
(*this).denominator = denominator;
error = "";
}
//and also I had to move obj creation
//out of try block, and therefore
//because of set_denominator(); handles exception
// I had to forget initializing when creating obj
//and instead used set methods
int main() {
exceptionHandlingV5 ob;
ob.setNumerator(4);
try {
ob.setDenominator(0);
// logic
cout << ob.divide();
}
catch(char const *e)
{
// I can only print errors now
// can't keep reading
ob.print_errors();
}
}
【问题讨论】:
-
你在 readAgain() 中调用构造函数不是你。 “exceptionHandlingV2(分子,温度);” .该行为是正确的,因为您在 readAgain() 中创建了新对象,并且该对象在函数结束时被销毁。
-
也是一个设计问题 - 在构造函数
exceptionHandlingV2::exceptionHandlingV2中捕获异常是没有意义的,因为无法使用给定的值正确构造对象exceptionHandlingV2。让异常从构造函数中传播出去是正确的设计。 -
你真的不应该在构造函数中与用户交互。
-
@RichardCritten 你们如何看待 v3 设计?编辑的问题是完美的吗?还是我做错了?
-
您仍在通过
readAgain与用户进行交互。那时你甚至不知道零是被计算出来的,是从标准输入中读取的,还是从其他地方读取的(想象一下从文件中读取一百万个,并且每次遇到零分母时都必须输入一个新值- 你会对程序员很生气)。处理构造异常的适当位置是在类之外。
标签: c++ oop exception class-extensions