C ++在异常方面遇到麻烦

时间:2013-06-28 07:00:46

标签: c++ exception

我遇到了C ++异常的问题,涉及异常的结构以及如何传递参数等等。

从此页面:http://www.cplusplus.com/doc/tutorial/exceptions/

1)当你抛出一些东西时,例如:throw 20;,你是否将20传递给int e,如果是这样的话,如果只是你的话,抛出一个整数是什么意思通过键入命令来响应屏幕?

2)如果程序遇到异常并抛出某些东西,那么程序是否会捕获以解决程序中的问题,或者程序是否只是为了响应错误已经发生并且您需要修复该程序。

3)查看标准异常部分:底部显示的异常(bad_allocbad_castbad_exception,...等)应该是异常的类型可以传递给变量吗?就像你说catch(bad_exception& e)一样,e唯一可以接收的是一个不适合任何其他异常类型的数字/浮点数/字符?老实说,我对标准异常非常困惑。

4)在标准例外情况中,exceptions中的class myexception: public exception是一个构造函数吗?

对不起,很长的帖子。任何简化主题,建议或帮助的在线教程都非常感谢。谢谢:))

1 个答案:

答案 0 :(得分:3)

这个答案可能高于你的水平,但我希望它至少让你基本了解抛出异常时会发生什么。它至少会给你一些可谷歌的条款。

throw语句不是立即函数调用。这是构建某个对象的程序中的一个点(无论是intstd::exceptionstd::runtime_error还是任何其他类型的对象)。

构造异常对象后,堆栈被展开。这是一个重要的概念,我将尝试用几个词来描绘它。展开堆栈意味着您调用的所有函数都以相反的顺序遍历,并且这些函数中分配的所有对象(在堆栈中)都被破坏。此过程继续向后,直到达到catch块,捕获您的异常类型(此处适用正常的函数重载决策规则,因此可以进行转换)。

一个说明性的例子:

#include <iostream>
#include <memory>
#include <string>

class my_exception
{
public:
  my_exception(const std::string& message) : message(message) {}
  const std::string& what() { return message; }
private:
  const std::string message;
};

void boo()
{
  int local = 5; // local, "automatic storage duration" variable
  throw my_exception("boo threw");
}
void bam()
{
  int* i = new int(42); // dynamically allocated int, unowned, accessible
  std::unique_ptr<int> j(new int(43)); // dynamically allocated int, owned by a smart pointer with automatic storage duration
  boo();
  delete i;
}

void f()
{
  try
  {
    bam();
  }
  catch(const my_exception& e)
  {
    std::cout << e.what();
  }
}

int main()
{
  f();
}

出汗的过程如下:

  1. main已输入
  2. f()被称为
  3. try阻止输入
  4. bam()被称为
  5. 动态分配int。构建具有自动存储持续时间的int i的指针(在堆栈上)
  6. 创建一个unique_ptr对象,其中包含指向另一个动态分配的int的指针。
  7. boo()被称为
  8. 构建自动存储持续时间的int
  9. 构造了my_exception类型的对象,并开始堆栈展开。
  10. boo()被遗忘,local被破坏(清理)
  11. 我们回到bam()并将其抛在后面:调用第一个j的析构函数,在值为delete的整数上调用43。然后指针对象i被破坏,但它指向的整数不是delete d。我们有内存泄漏(永远不会达到delete i;语句。)
  12. 我们回到f(),友好的catch抓住我们的my_exception并输出message std::cout
  13. 回答你的问题:

    1)不,会发生一个更复杂的过程,最终会在步骤12中结束,这可能类似于一个函数调用,但事实并非如此。

    2)见上文。

    3)catch“接收”一个对象。它的功能与函数重载非常相似。挑选最好的一个。如果没有匹配,则继续展开。 e不会“收到”任何内容。它可能是由抛出的任何东西构造的,但这要求e的类型具有正确的转换/构造函数。

    4)否。它指定继承。例如:

    #include <stdexcept>
    
    class my_exception : public std::exception
    {
    public:
      my_exception(const std::string& message) : std::exception(message) {}
    }
    

    my_exception类继承what()中定义的std::exception函数,因此我无需自行定义。