如何创建例外? [英] How to create exceptions?

查看:174
本文介绍了如何创建例外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个即将到来的任务处理异常,并在我当前的通讯录程序中使用它们,大多数家庭作业是围绕。我决定玩例外和整个尝试catch事情,并使用类设计,这是我最终将为我的任务在几个星期内做。我有工作代码检查异常只是罚款,但我想知道的是,如果有一种方法来标准化我的错误消息函数,(即我的what()调用):

So I have an upcoming assignment dealing with exceptions and using them in my current address book program that most of the homework is centered around. I decided to play around with exceptions and the whole try catch thing, and using a class design, which is what I will eventually have to do for my assignment in a couple of weeks. I have working code that check the exception just fine, but what I want to know, is if there is a way to standardize my error message function, (i.e my what() call):

这里是我的代码:

#include <iostream>
#include <exception>
using namespace std;


class testException: public exception
{
public:
  virtual const char* what() const throw() // my call to the std exception class function (doesn't nessasarily have to be virtual).
  {
  return "You can't divide by zero! Error code number 0, restarting the calculator..."; // my error message
  }

  void noZero();

}myex;  //<-this is just a lazy way to create an object



int main()
{
void noZero();
int a, b;

cout << endl;

cout << "Enter a number to be divided " << endl;

cout << endl;

cin >> a;

cout << endl;

cout << "You entered " << a << " , Now give me a number to divide by " << endl;

cin >> b;

try
{    
    myex.noZero(b); // trys my exception from my class to see if there is an issue
}
catch(testException &te) // if the error is true, then this calls up the eror message and restarts the progrm from the start.
{
    cout << te.what() << endl;
    return main();
}

cout <<endl;

cout << "The two numbers divided are " << (a / b) << endl;  // if no errors are found, then the calculation is performed and the program exits.

return 0;

}

  void testException::noZero(int &b) //my function that tests what I want to check
  { 
    if(b == 0 ) throw myex;  // only need to see if the problem exists, if it does, I throw my exception object, if it doesn't I just move onto the regular code.
  }

我想要做的是让它成为我的)函数可以返回一个取决于被调用的错误类型的值。因此,例如,如果我调用一个错误,看起来是一个顶部的数字,(a),看看它是否为零,如果是,然后将设置消息说,你不能分子为零,但仍然在what()函数内。例如:

What I would like to be able to do is make it so my what() function can return a value dependent on what type of error is being called on. So for instance, if I were calling up an error that looked a the top number,(a), to see if it was a zero, and if it was, it would then set the message to say that "you can't have a numerator of zero", but still be inside the what() function. Here's an example:

  virtual const char* what() const throw() 
  if(myex == 1)
  {
      return "You can't have a 0 for the numerator! Error code # 1 "
  }
  else

  return "You can't divide by zero! Error code number 0, restarting the calculator..."; // my error message
  }

这显然不会工作,

推荐答案

你的代码包含了很多误解。简单的答案是肯定的,你可以改变 what()为了返回任何你想要的。

Your code contains a lot of misconceptions. The short answer is yes, you can change what() in order to return whatever you want. But let's go step by step.

#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
using namespace std;


class DivideByZeroException: public runtime_error {
public:

  DivideByZeroException(int x, int y)
    : runtime_error( "division by zero" ), numerator( x ), denominator( y )
    {}

  virtual const char* what() const throw()
  {
    cnvt.str( "" );

    cnvt << runtime_error::what() << ": " << getNumerator()
         << " / " << getDenominator();

    return cnvt.str().c_str();
  }

  int getNumerator() const
    { return numerator; }

  int getDenominator() const
    { return denominator; }

  template<typename T>
  static T divide(const T& n1, const T& n2)
    {
        if ( n2 == T( 0 ) ) {
            throw DivideByZeroException( n1, n2 );
        } 

        return ( n1 / n2 );
    }

private:
    int numerator;
    int denominator;

    static ostringstream cnvt;
};

ostringstream DivideByZeroException::cnvt;

首先, runtime_error exception ,是从中派生的adviced异常类。这是在stdexcept头中声明的。您只需要使用您要在 what()方法中返回的消息初始化其构造函数。

In the first place, runtime_error, derived from exception, is the adviced exception class to derive from. This is declared in the stdexcept header. You only have to initialize its constructor with the message you are going to return in the what() method.

其次,你应该恰当地命名你的类。我理解这只是一个测试,但一个描述性的名称将总是有助于阅读和理解你的代码。

Secondly, you should appropriately name your classes. I understand this is just a test, but a descriptive name will always help to read and understand your code.

如你所见,我已经改变了构造函数接受引起异常的数字。你在异常中做了测试...嗯,我尊重这个,但作为一个可以从外部调用的静态函数。

As you can see, I've changed the constructor in order to accept the numbers to divide that provoked the exception. You did the test in the exception... well, I've respected this, but as a static function which can be invoked from the outside.

最后, what()方法。由于我们要分两个数字,所以很好地显示引发异常的两个数字。实现它的唯一方法是使用ostringstream。这里我们使它静态,所以没有返回一个指向堆栈对象的问题(即, cnvt 一个局部变量会引入未定义的行为)。

And finally, the what() method. Since we are dividing two numbers, it would be nice to show that two numbers that provoked the exception. The only way to achieve that is the use of ostringstream. Here we make it static so there is no problem of returning a pointer to a stack object (i.e., having cnvt a local variable would introduce undefined behaviour).

程序的其余部分或多或少是你在你的问题中列出的:

The rest of the program is more or less as you listed it in your question:

int main()
{
int a, b, result;

cout << endl;

cout << "Enter a number to be divided " << endl;

cout << endl;

cin >> a;

cout << endl;

cout << "You entered " << a << " , Now give me a number to divide by " << endl;

cin >> b;

try
{    
        result = DivideByZeroException::divide( a, b );

    cout << "\nThe two numbers divided are " << result << endl;
}
catch(const DivideByZeroException &e)
{
    cout << e.what() << endl;
}

return 0;

}

如您所见, c $ c> return main()指令。这没有意义,因为你不能递归调用 main()。此外,这样做的目的是一个错误:你希望重试引发异常的操作,但这是不可能的,因为异常不可重入。然而,您可以更改源代码一点,以实现相同的效果:

As you can see, I've removed your return main() instruction. It does not make sense, since you cannot call main() recursively. Also, the objective of that is a mistake: you'd expect to retry the operation that provoked the exception, but this is not possible, since exceptions are not reentrant. You can, however, change the source code a little bit, to achieve the same effect:

int main()
{
int a, b, result;
bool error;

do  {
    error = false;

    cout << endl;

    cout << "Enter a number to be divided " << endl;

    cout << endl;

    cin >> a;

    cout << endl;

    cout << "You entered " << a << " , Now give me a number to divide by " << endl;

    cin >> b;

    try
    {    
        result = DivideByZeroException::divide( a, b ); // trys my exception from my class to see if there is an issue

        cout << "\nThe two numbers divided are " << result << endl;
    }
    catch(const DivideByZeroException &e) // if the error is true, then this calls up the eror message and restarts the progrm from the start.
    {
        cout << e.what() << endl;
        error = true;
    }
} while( error );

return 0;

}

正如你所看到的,

希望这有助于。

这篇关于如何创建例外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆