【问题标题】:try catch block in c++ class ussage在 C++ 类用法中尝试 catch 块
【发布时间】: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


【解决方案1】:

感谢@sonulohani、@RichardCritten 和@molbdnilo 指导我并修改了我的愚蠢问题,我的意思是现在我看到了我的第一个设计,我发现我犯了很多错误和错误,我被你解决了帮助和 cmets。无论如何,我终于修改了我的整个设计并为 Division 创建了一个新的类和 main() 函数。我一开始想做的就是在课堂上练习运行时错误处理,现在我想我终于明白了。这是最后一个设计。它可能会帮助将来的人。

#ifndef EXCEPTION_HANDLING_FINAL_V1_EXCEPTION_HANDLING_FINAL_V1_H
#define EXCEPTION_HANDLING_FINAL_V1_EXCEPTION_HANDLING_FINAL_V1_H
class exception_handling_final_v1 {
private:
    double numerator;
    double denominator;
    char * error;
public:
    exception_handling_final_v1();
    exception_handling_final_v1( double , double );

    void set_numerator ( double );
    void set_denominator ( double );

    double divide ( );
    char * errors();
};
#endif //EXCEPTION_HANDLING_FINAL_V1_EXCEPTION_HANDLING_FINAL_V1_H

#include "exception_handling_final_v1.h"
exception_handling_final_v1::exception_handling_final_v1() {
    numerator = 1;
    denominator = 1;
    error = "";
}
exception_handling_final_v1::exception_handling_final_v1( double numerator,
                                                          double denominator) {
    set_numerator( numerator );
    set_denominator ( denominator );
}
void exception_handling_final_v1::set_numerator ( double numerator ){
    (*this).numerator = numerator;
}
void exception_handling_final_v1::set_denominator( double denominator ) {
    if ( !denominator ){
        error = "denominator can not be zero\n";
        throw "denominator can not be zero\n";
    }
    (*this).denominator = denominator;
    error = "";
}
double exception_handling_final_v1 :: divide () {
    return denominator / numerator;
}
char * exception_handling_final_v1::errors() {
    return error;
}
#include <iostream>
#include "exception_handling_final_v1.h"
using namespace std;

int main() {

    exception_handling_final_v1 ob;
    double numerator , denominator , result;
    cout << "enter nummerator\n";
    cin >> numerator;
    ob.set_numerator( numerator );

    cout << "enter denominator\n";
    cin >> denominator ;

    try{
        ob.set_denominator( denominator );
        result = ob.divide();
    }
    catch( char const * error){
        cout << ob.errors();
    }

    cout<<"bye";
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2023-03-18
    • 2013-09-23
    • 2023-03-15
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多