Clear explanation required: throw () and untwisted pants

I am not a programmer, but I learned a lot by watching others. I write wrapper classes to make things easier with the really technical API I'm working with. Its procedures return error codes, and I have a function that converts them to strings:

static const char* LibErrString(int errno);

For consistency, I decided that a member of my classes throws an exception when an error occurs. I created a class:

struct MyExcept : public std::exception {
   const char* errstr_;
   const char* what() const throw() {return errstr_;}
   MyExcept(const char* errstr) : errstr_(errstr) {}
};

Then in one of my classes:

class Foo {
public:
   void bar() {
   int err = SomeAPIRoutine(...);
   if (err != SUCCESS) throw MyExcept(LibErrString(err));
   // otherwise...
   }
};

Everything works fine: if it SomeAPIRoutinereturns an error, the try-catch block around the call Foo::barcatches the standard exception with the correct error string in what().

Then I wanted the member to provide additional information:

void Foo::bar() {
   char adieu[128];
   int err = SomeAPIRoutine(...);
   if (err != SUCCESS) {
      std::strcpy(adieu,"In Foo::bar... ");
      std::strcat(adieu,LibErrString(err));
      throw MyExcept((const char*)adieu);
   }
   // otherwise...
}

, SomeAPIRoutine , what(), , . , , adieu throw. , adieu Foo. : try-call Foo::bar, , () what().

, : ( ), if-, ""? , , . , (), ++ .

+3
3

: , .

   char adieu[128];

Foo:: bar.

" " ( " " ) . , ( "push" , ). - , , - , ( "" " " , ').

, , " " " " "" , , , , .

+4

:

struct MyExcept : public std::exception {
   std::string errstr;
   const char* what() const throw() {return errstr_.c_str();}
   MyExcept(int errno, std::string prefix = "") : errstr (prefix + LibErrString(errno)) {}
};
...
throw MyExcept(err, "In Foo::bar... ");

C . , (- ), C . , ++ . - .

LibErrString . -.


, . , ? ++ , . try{ }, , , : , , .

. , , . , , , ; - .

, , LIFO. , . , . , . , ++ , .

+1

-, :

class MyExcept : public std::runtime_error {
    MyExcept(const std::string & message) : std::runtime_error(message) {}
};

, . std::logic_error, (. , ). :

void Foo::bar() {
    int err = SomeAPIRoutine(...);
    if (err != SUCCESS) {
       throw MyExcept("Error: " + LibErrString(err));
   }
   // otherwise...
}

FAQ , , :

try {
    // fail here
}
catch (std::exception & e) { // NOTE: catch by reference!!!
}

As for your stack question, the current stack frame is unwound, and all objects in it are destroyed in the reverse order of their design. This is done until an exception is detected. It is for this reason that RAII works.

0
source

All Articles