0

Let's say I have a function (mnHw) that calculates the mean of a vector (a vector of homework grades). This function throws a domain_error("Student did no homework") exception when the vector is empty. When I call mnHw from main, things are simple when I want to print out the error:

        try
        {
            cout  <<  mnHw(student.homework);
        }
        catch (domain_error e)
        {
            cout << e.what();
        }

However, things are complicated if I only want to store the mean homework grade, instead of vector of all grades, for the student. In that case I call mnHw within the function that reads in the student information (readStudent), and put up a flag (-1) when no homework is entered:

        try
        {
            student.finalGrade=mnHw(hwGrades);
        }
        catch (domain_error e)
        {
            student.finalGrade = -1;
        }

Then, within main, I can do the following to recover the error:

    if (allStudents[i].finalGrade == -1) 
        cout << "Student did no homework";
    else  
        cout << allStudents[i].finalGrade;

Intuitively, though, this flag method seems less elegant than having the actual error message pass directly to main, at least for those cases when I want to display it from main (which is the case here). Is there some trick or technique I am missing that would directly give main access to e.what() from mnHw?

What is good practice?

Note I have full functions for each of these cases that I could post, but they seemed too long. Please let me know if I should have included them to make myself more clear. Also, please feel free to correct any other mistakes I’m making. I am just now learning C++ the right way, and want to be corrected as much as possible. <flame-retardant vest>

eric
  • 7,142
  • 12
  • 72
  • 138
  • 2
    "this flag method seems less elegant than having the actual error message pass directly to main" - not quite. Personally, I hate functions that are supposed to do computations, but they are printing to stdout/stderr. It hurts my sense of balance. :P If a function is doing computation, then let it do its task then return either a valid value, or an out-of-range value in order to signal an error. Then its user/client/caller (think of your code as if it was going to be a library!) can do whatever it wants to when it encounters an error. –  Feb 01 '14 at 18:19
  • 1
    Why not let your funcion throw the exception and do the catch on `main`? – wesley.mesquita Feb 01 '14 at 18:25
  • @wesley.mesquita: that's what the first version does (the first block of code in my original post is from main). But the question is, how do I do this in main when the exception-throwing function is called by another function? Note this is part of my self-study of problem 4.6 of **Accelerated C++**. I think the main point of this question is to figure out this puzzle. My "solution" is to use a flag, but I can't help but think there should be a better way. – eric Feb 01 '14 at 18:37

1 Answers1

1

You can re-throw the exception catched (const domain_error* e){ throw e;}. Or better, you can create based on domain_error create another exception i.e., student_final_grade_exceptionand throw it.

EDIT:

Something like:

 try
        {
            student.finalGrade=mnHw(hwGrades);
        }
        catch (domain_error& e)
        {
              student_final_grade_exception mean_excep;
              mean_excep.addInfo("Error in calculation means...");
              mean_excep.addInfo(e.what()); 
              throw mean_excep;
        }

And then, you prepare your main to catch student_final_grade_exception. Of course, there is a litle bit more work to create a new exception type, but it can make possible to get more info and let the functions to only what they suppose to do as were told.

wesley.mesquita
  • 795
  • 5
  • 12
  • Thanks I'll try this. Any recommendations for good sources with quick explanation of how to make a new exceptio type? – eric Feb 02 '14 at 13:28
  • 1
    @neuronet Take a look [here](http://stackoverflow.com/questions/8152720/correct-way-to-inherit-from-stdexception). I used to inherit from `std::exception`, but seems to be a better pratice to it from `std::runtime_error` or `std::logic_error`. – wesley.mesquita Feb 02 '14 at 15:10
  • I wonder if there is a worked out example for novices...that is pretty esoteric for someone on chapter 4 of an intro book? Maybe I should just cut my losses now and come answer this with a fully annotated example from head to toe once I have done classes....Though this link seems helpful: http://stackoverflow.com/questions/16182781/creating-exceptions-c – eric Feb 12 '14 at 23:57