2017-03-25 20 views
0

私はC++を信じられないほど新しいですし、例外処理のためのテストプログラムを作成するという課題があります。特定のクラスで定義されたものとmainで定義したものの両方を例外にするのに問題があります。誰かが私が持っているものを見渡して、どこが間違っているのかを指摘できますか?C++例外処理:例外をオブジェクトとして定義する

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

テストプログラムのための私のコード:教授から


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

私は唯一の例外投げとして簡単にテスト用のループはややランダムである必要があり。 catch(...)を使用すると例外が発生します。私が間違っていることのヒント?

答えて

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

これはそれを行う方法ではありません。 catchは実際の例外をキャッチしません。それを引数にする必要があります。

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

catch(StudentException())は、関数型をキャッチしようとします。あなたは

catch (StudentException& se) 

をしたい(そして、あなたは新しい関係のないStudentExceptionを構築するのではなく、ハンドラでseを使用することができます。)

1
catch(StudentException()) { 
    ... 
} 

これは間違っている構文です。あなたは

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

はだけでなく、この方が簡単です例えば、例外がstandard library's exception classesのいずれかから継承するため

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

私たちがここにいる間は、それが通常は良いアイデアだと言う必要があります実装することができますが、それはまた、人々が通常例外メッセージを見つけるために探す、メンバ関数what()を提供します。