首页 文章

C - 关于抛出异常的几个问题

提问于
浏览
2

关于在C中抛出异常,我有几个问题 . 据我所知,他们......

可以从main()函数中抛出异常 . 任何可以在main()函数中抛出异常的代码块都应该被try和catch语句包围,如下所示

void foo(//args) {
     if (...) {
      throw "Error reached";
     } ...

    int main() {
     ...
     try {
      //Code that can throw an excpetion
     } catch(const char* msg) (
      cerr << msg << endl;
     } 
     ...
    }

**In the example above, why is the argument to the catch a const char . Doesn't C++ allow for strings? Also, is it possible to throw an exception that isn't a const char , like an int? or a char?

Does throwing an exception in foo, terminate the foo function?

Are there cases where you could put the try and catch statements in the same function as the throw?

对不起,如果这些是基本问题 . 谢谢你

2 回答

  • 6

    为什么catch的参数是一个const char *

    因为你把字符串文字扔掉了 const char* . 简而言之,你 grab 你扔的东西 .

    C不允许字符串吗?

    它确实如此,但要捕获字符串,您需要首先抛出字符串 .

    是否可以抛出一个不是const char *的异常,

    你可以扔任何东西 . 抛出特殊的异常类是一个好主意,比如 std::exception 并从中派生出来 .

    在foo中抛出异常,终止foo函数?

    是的,它确实 .

    是否有可以将try和catch语句放在与throw相同的函数中的情况?

    如果你愿意,你可以做到 . 做这件事的情况并不多 .

    看起来您需要获得一本好书并阅读有关异常的章节 . 在此期间this super-FAQ entry可能会帮助你/

  • 2

    您可以抛出任何类型的对象 .

    EDIT: (希望我现在能做到这一点)你所做的就是抛出一个C字符串,在这种情况下是 const char[13] 类型 . C-Arrays将衰减为指向其第一个元素的指针,在本例中为 const char* 类型的指针 .

    通常,您要做的是抛出预定义的异常对象 . 它们可以在头文件 <stdexcept> 中找到,并且派生自基类 std::exception . 派生的异常类例如是 std::logic_errorstd::range_errorstd::bad_alloc 等 .

    它们的构造函数将字符串作为参数,因此您可以使用它

    throw std::logic_error{"Negative values not allowed."};
    

    可以在catch语句中访问此消息,如下所示:

    catch(std::exception &e) // capture reference to base class
    {
        std::cout << e.what() << '\n'; // what() of derived is called, since virtual
    }
    

    如果捕获到异常,则会发生所谓的堆栈展开 . 然后,您可以在本地处理错误,或重新抛出异常 . 只有当抛出异常并且从未捕获到异常时,才调用std :: terminate()程序中止 .

    您可以将try / catch语句放在任何位置 . 但是,请记住"exception"实际上意味着什么 . 使用简单的条件表达式 if (n < 0) break; 等易于处理的案例不需要异常处理 . 特别是如果你能够真实地期望这种不需要的条件经常是真实的 . 然后它不是"exceptional" .

    如果您决定使用异常处理错误并且可以在本地处理它们,则可以在main()的开头和结尾放置try / catch子句 .

    由于您可以在try语句之后直接放置 several catch语句,然后您可以开始处理更具体的错误,或者只是通过 catch(...) { //... } 捕获 anything .

    这些都是非常详细的描述(包括 whenwhen not 上的指针,以便在_1658241中使用它 .

    EDIT: 这是一个使用try / catch语句的例子 . 但是,没有捕获异常对象,而是一个int(错误) . 只是为了证明,你可以真正地抛出/ grab 任何你喜欢的东西 . 设 process_several_files() 是嵌套在代码中的某个函数:

    std::vector<std::string> process_several_files(std::vector<std::string> const& files)
     {
          std::vector<std::string> contents{};
          contents.reserve(files.size()); // files contains file names from user input
          for (auto const& file : files)
          {
               try
               {
                    contents.emplace_back(get_file_contents(file.c_str())); // A "C like" function. get_file_contents() will throw "errno", if a file does not exist
               }
               catch(int err)
               {
                    std::cerr << "***Error while opening " << file << " : " << std::strerror(err) << "***\n";
                    continue;                   // "scope" didn't change, just keep iterating!
               }
          }
          return contents;
     }
    

相关问题