简体   繁体   中英

C++ Exception Handling: defining exception as object

I am incredibly new to C++ and I have an assignment to create a test program for exception handling. I am having problems catching the exceptions, both those defined in the given classes and those I have defined in main. Could someone look over what I have and point out where I'm going wrong?


From the professor:

#ifndef STUDENT_H
#define STUDENT_H
#include <string>
using namespace std;

class Student
{
public:
    Student();
    Student(string thisStudentID);
    void enroll(string thisSectionID);
private:
    string studentID;
    bool timeToThrow();
    static int sneakyCount;
};
#endif

#include <string>
#include <iostream>
#include "Student.h"
#include "StudentException.h"
using namespace std;

// The constructor for this class accepts a Student ID
Student::Student(string thisStudentID)
{
    // This first statement updates a variable used to help decide when to      Throw an Exception
    sneakyCount++;
    // Any text will be accepted as the student ID in this implementation
    if (!timeToThrow())
        studentID = thisStudentID;
    else
        throw StudentException("Student " + thisStudentID + " has been      expelled from this school");
}
// This default constructor shouldn't be used, so throwing an exception     isn't so artificial, its
// the right thing to do.  We will also find out if this constructor gets     called at time that we don't expect.
Student::Student()
{
    // This first statement updates a variable used to help decide when to     Throw an Exception
    sneakyCount++;
    throw StudentException("Incorrect Call to Student Constructor - No     Student ID Provided");
}
// This dummy function would enroll the student in a course
void Student::enroll(string thisSectionID)
{
    // This first statement updates a variable used to help decide when to      Throw an Exception
    sneakyCount++;
    if (!timeToThrow())
        cout << endl << "Student: " << studentID << " is now enrolled in "     << thisSectionID << endl;
    else
        throw StudentException("Section " + thisSectionID + " has been     cancelled");
    return;
}
// This is the code that helps decide when to throw an exception.  You are     welcome to look at it,
// but its only here to help generate unexpected exceptions.  It will vary     in different versions of Student
// as I play around with it. 
int Student::sneakyCount = 0;

bool Student::timeToThrow()
{
    if (sneakyCount == 4)
        return true;
    else
        return false;
}

#ifndef STUDENTEXCEPTION_H
#define STUDENTEXCEPTION_H
#include <string>
using namespace std;

class StudentException
{
public:
    StudentException(string thisErrorMessage);
    string errorMessage();
private:
    string message;
};
#endif

#include <string>
#include "StudentException.h"
using namespace std;

StudentException::StudentException(string whatWentWrong)
{
    // Set the stored message within the object
    // Any text will be accepted as the error message
    message = whatWentWrong;
}
// Return the error message stored inside the object
string StudentException::errorMessage()
{
    return message;
}

My code for the test program:

#include <iostream>
#include <string>
#include "StudentException.h"
#include "Student.h"

using namespace std;
int main()
{
    char again = 'n';
    do
    {
        try
        {
            Student testStudent1("S0000001");
            testStudent1.enroll("CSC-160-500");
        }
        catch(StudentException())
        {
            StudentException testException1("Pre-requisites required");
            cout << testException1.errorMessage();
        }
        cout << "Again?\n";
        cin >> again;
    }
    while(tolower(again) == 'y'); 
return 0;
}

I only have the loop for easier testing as the Exception throwing is somewhat random. I only catch exceptions if I use catch(...). Any hints on what I'm doing wrong?

catch(StudentException()) tries to catch a function type. You want

catch (StudentException& se)

(and then you can use se in the handler instead of constructing a new unrelated StudentException .)

catch(StudentException()) {
   ...
}

This is the wrong syntax. You need to say

catch(const StudentException& e) {
    ...
}

While we're here, it's usually a good idea for exceptions to inherit from one of the standard library's exception classes , for example

class StudentException : public std::runtime_error
{
public:
    StudentException(const string& thisErrorMessage)
        : std::runtime_error(thisErrorMessage)
    {}
};

Not only does is this easier to implement, but it also provides the what() member function, which people will usually look for to find the exception message.

catch(StudentException())
{
    StudentException testException1("Pre-requisites required");
    cout << testException1.errorMessage();
}

That's not the way to do it. Your catch doesn't catch the actual exception, you should make it an argument :

catch(const StudentException& ex)
{
    cout << ex.errorMessage();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM