用户定义的异常处理

时间:2018-03-28 06:38:16

标签: c++

这是一个c ++程序,使用5个标记来计算平均值和等级。 如果输入的标记大于100或小于0,则应抛出学生异常。

#include<iostream>
#include<exception>
using namespace std;
class lessex:public exception
{
    public:
        void what()
        {
            cout<<"Mark less than 0"<<endl;
        }
};
class morex:public exception
{
    public:
        void what()
        {
            cout<<"Mark greater than 100"<<endl;
        }
};
class student
{
    string name;
    string rollno;
    int marks[5];
    double avg;
    char g;
    public:
    void get();
    void aveg();
    void grade();
    void print();
};
void student::get()
{
    cin>>name;
    cin>>rollno;
    for(int i=0;i<5;i++)
    {
        try{
        cin>>marks[i];
        if(marks[i]>100)
        {
            morex d;
            throw d;
        }
        }
        catch(morex &e)
        {
            /*e.what();*/
            throw ;
        }
        try{
        if(marks[i]<0)
        {
            lessex d;
            throw d;
        }
        }
        catch(lessex &e)
        {
            /*e.what();*/
            throw ;
        }
    }
}
void student::aveg()
{
    int sum=0;
    for(int i=0;i<5;i++)
    {
        sum=sum+marks[i];
    }
    avg=sum/5;
}
void student::grade()
{
    if(avg>90)
    g='S';
    else
    g='Z';
}
void student::print()
{
    cout<<name<<endl;
    cout<<rollno<<endl;
    cout<<g<<endl;
}
int main()
{
    student s;morex e;lessex e1;
    try{
    s.get();
    }
    catch(morex &e)
    {
        e.what();
    }
    catch(lessex &e1)
    {
        e1.what();
    }
    s.aveg();
    s.grade();
    s.print();
    return 0;
}

但是,在主函数中遇到异常后,我的程序没有成功退出。

为什么它继续使用s.aveg,等级等。

3 个答案:

答案 0 :(得分:2)

  

为什么我的程序在遇到来自main函数的异常后才退出?为什么它继续使用s.aveg,等级等。

您捕获异常,然后离开catch块。之后正常执行。在处理程序块的末尾不会自动重新抛出异常。如果您无法处理错误并继续运行,那会非常令人抓狂:

如果要重新抛出异常,则需要在处理程序中添加显式throw;。就像你在student::get()中已经做过的那样。或者只是没有try-catch块。该计划将在没有&#34; s.aveg,等级等的情况下终止。被执行。

或者,假设您的意图不是终止,而是在不执行其他功能的情况下正常退出,您可以按照user4581301的建议进行操作。将这些函数调用移动到try块中。这样,如果在执行之前抛出异常,它们将不会在处理程序之前或之后运行。

答案 1 :(得分:1)

在捕获异常后继续执行,而不退出,这就是程序没有退出的原因。

首先,您应该遵循what返回字符串并且不打印任何内容的约定:

class lessex : public exception
{
    public:
        const char* what() const noexcept override
        {
            return "Mark less than 0";
        }
};

class morex : public exception
{
    public:
        const char* what() const noexcept override
        {
            return "Mark greater than 100";
        }
};

然后,你在get;

中过度复杂化了很多事情
void student::get()
{
    cin >> name;
    cin >> rollno;
    for(int i = 0; i < 5; i++)
    {
        cin >> marks[i];
        if (marks[i]>100)
        {
            throw morex();
        }
        if(marks[i]<0)
        {
            throw lessex();
        }
    }
}

和异常不应该像错误代码一样使用并且在每次潜在抛出调用之后被捕获,你通常会编写“快乐路径”(假定为无错误的路径)并处理它之外的异常:

int main()
{
    try
    {
        // This part handles the normal case, assuming that all goes well.
        student.s;
        s.get();
        s.aveg();
        s.grade();
        s.print();
    }
    // This part handles the exceptional case when something goes wrong.
    catch (std::exception& ex)
    {
        std::cerr << ex.what();
    }
}

(你的设计有些疑问,因为从get投掷会使对象处于无效状态。你可能想重新考虑它。)

答案 2 :(得分:0)

它仍在继续,因为在您捕获异常后,您不会对此做任何事情。当抛出特定异常时,您必须指定在catch块内部执行的操作。

或者您也可以在s.aveg();

中移动其他功能,例如s.grade(); s.print(); try{ s.get(); }

这样可以防止aveg,等级和打印功能在执行命令后停止执行