c++oopexceptionclass-extensions

try catch block in c++ class ussage


this is v1 which results in errors

#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;
}

this is v2 design which i stopped interacting with user in constructor

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();
    }

}

in v3 design I added a new function to handle exception inside the class itself

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 = "";
}

I made a v4 design to stop handling exception in class , rather doing it in main(). which one is correct ? handling exception in class or just throwing exception from class and handling in main ?,and the thing is I can no longer keep reading readAgain() from user until user enters the write input, because exception will go inside catch block and can't handle runtime error in catch block so I deleted readagain() function from design and only printed errors in main() part

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();
    }
}

Solution

  • thanks to @sonulohani , @RichardCritten and @molbdnilo for guiding me and revising my stupid question ,I mean now that I look at my very first design, I see I made a lot of mistakes and errors that I got around by your helps and comments. anyway I finally revised my whole design and made a new class and main() func for division . all I wanted to do in first place was to practice runtime error handling from class, and now I think I finally got it. here is the last design. it might help someone out there in future.

    #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;
    }