1

我正在阅读第 16 章,以便开始我的 C++ 课程作业。本节介绍异常处理。我理解 try/catch 构造背后的概念,但是,书中的一个例子让我有点困惑。我希望对这是如何工作的一些解释。示例代码如下:

// Includes, header guards, and namespace std...
class IntRange
{
 private:
  int intput;
  int lower;
  int upper;

 public: 
  // Exception class
  class OutOfRange { }; // This is exactly how it appears in the text.

  IntRange(int low, int high) { lower = low; upper = high; }
  int GetInput()
  {
    cin >> input;
    if (input < lower || input > upper)
      throw OutOfRange(); // <-- This is my question in particular. What is this?
    return input;
  }
};

// End header guard.

// Program entry point.

int main()
{
  IntRange range(5, 10)
  int userValue;

  cout << "Enter a value in the range 5 - 10: ";
  try
  {
    userValue = range.getInput();
    cout << "You entered " << userValue << endl;
  }
  catch (IntRange::OutOfRange) // <-- Again, what is this delcaration and how can
                               // this data type be defined when IntRange does not
                               // have a default constructor?
  {
    cout << "That value is out of range.\n";
  }

  return 0;
}

代码与教科书中的代码完全相同,除了我将一些内容放在同一行以防止问题变得很长。

如果您发现任何错误,很可能是拼写错误,但最重要的几点已经过仔细检查。

4

4 回答 4

2
 throw OutOfRange();

这将创建一个新的 class 实例OutOfRange并将throw其保存。请记住,您还可以像这样创建一个实例:

my_method( MyClass() );

代替:

MyClass obj; 
my_method( obj );

现在:

catch (IntRange::OutOfRange)

OutOfRange是 的内部或嵌套IntRange。看这里

于 2012-04-15T15:30:43.307 回答
1
  throw OutOfRange(); // <-- This is my question in particular. What is this?

这个默认构造一个对象OutOfRange然后抛出它。
即使您没有在类中定义方法,编译器也会自动为您生成一对,其中一个是默认构造函数。因此,即使您没有指定构造函数,那里也会有一个(在规则 3/5 上搜索一下,以解释编译器生成的方法)。

catch (IntRange::OutOfRange) // <-- Again, what is this delcaration and how can
                             // this data type be defined when IntRange does not
                             // have a default constructor?

在这里,我们正在捕获一个类型的对象IntRange::OutOfRange注意:我们没有捕获IntRange. 我们正在捕获OutOfRange恰好在类内部定义的类IntRange(除了定义它的地方没有其他关系)。

另请注意:除非您禁用它,否则编译器将自动为所有类生成一个复制构造函数。因此,异常通常是从抛出点到捕获点的复制构造(稍微复杂一点)。所以你的异常对象必须是可复制的。

另请注意,最好通过 const 引用捕获异常:

catch (IntRange::OutOfRange const& e)

这避免了与切片对象相关的问题,这些对象是异常层次结构的一部分。

于 2012-04-15T15:36:20.080 回答
0

他们正在创建一个自定义异常(作为一个类)调用OutOfRange并抛出它。

这样,您可以通过这种方式专门捕获OutOfRange异常:

try
{
    //do something
}
catch (OutOfRange o)
{
    //you know the input was out of range
}
catch (Exception e)
{
    //something else went wrong
}
于 2012-04-15T15:31:03.047 回答
0

您的OutOfRange班级作为一个整体属于IntRange班级 - 它不属于该班级的任何特定对象。

为了使用OutOfRange,甚至不需要IntRange实际用作具体类,因为IntRange::OutOfRange只需指定完全限定的类型名而不是对象。

在 C++ 中,类型名称仅在编译时才重要;数据类型信息(以及变量名和代码中的各种其他内容)通常会被编译器完全剥离 - 数据类型仅用于帮助您编写代码和进行调试。

于 2012-04-15T15:31:05.893 回答