简体   繁体   中英

Throwing an exception

I have created one exception in a function like so:

void testing(int &X)
{
....
X=...
if (X>5)
throw "X greater than 5!"
}

and then in main.cpp

try
{
int X=0; 
testing(X);
}

catch (const char *msgX)
{
....
}

But now I would like to also introduce Y as X. and the prototype of testing will be :

void testing(int &X, int &Y)

My question, how can I throw two exceptions, in which if X>5, I throw an exception regarding X and if Y>10, I throw another exception about Y and I catch them all at the end in my main program?

In C++ it is impossible to have two exceptions "in flight" at the same time. If that condition ever arises (eg by a destructor throwing during stack unwinding), the program is terminated (with no way to catch the second exception).

What you can do is make a suitable exception class, and throw that. For example:

class my_exception : public std::exception {
public:
    my_exception() : x(0), y(0) {} // assumes 0 is never a bad value
    void set_bad_x(int value) { x = value; }
    void set_bad_y(int value) { y = value; }
    virtual const char* what() {
        text.clear();
        text << "error:";
        if (x)
            text << " bad x=" << x;
        if (y)
            text << " bad y=" << y;
        return text.str().c_str();
    }
private:
    int x;
    int y;
    std::ostringstream text; // ok, this is not nothrow, sue me
};

Then:

void testing(int &X, int &Y)
{
    // ....
    if (X>5 || Y>10) {
        my_exception ex;
        if (X>5)
            ex.set_bad_x(X);
        if (Y>10)
            ex.set_bad_y(Y);
        throw ex;
    }
}

Anyway you should never throw raw strings or integers or the like--only classes derived from std::exception (or perhaps your favorite library's exception classes, which hopefully then derive from there, but may not).

You can throw different exception types or you can through the same exception type with different content.

struct myexception : public std::exception
{
   std::string description;
   myexception(std::string const & ss) : description(ss) {}
   ~myexception() throw () {} // Updated
   const char* what() const throw() { return description.c_str(); }
};

void testing(int &X, int &Y)
{
   if (X>5)
      throw myexception("X greater than 5!")
   if (Y>5)
      throw myexception("Y greater than 5!")
}

try
{
   int X=0; 
   testing(X);
}
catch (myexception const & ex)
{

}

(btw. I did not down-vote...)

Here is a sketch:

class x_out_of_range : public std::exception {
  virtual const char* what() { return "x > 5"; }
};

class y_out_of_range : public std::exception {
  virtual const char* what() { return "y > 10"; }
};

Now in your function:

if (x > 5)
  throw x_out_of_range();

:

if (y > 10)
  throw y_out_of_range();

Now your catch code:

try
{
  :
}
catch (x_out_of_range const& e)
{
}
catch (y_out_of_range const& e)
{
}

NOTE: in any case, you can only throw one exception from the function...

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