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