抛出类中定义的类的对象

时间:2012-04-15 15:26:15

标签: c++ exception-handling try-catch

我正在阅读第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 个答案:

答案 0 :(得分:2)

 throw OutOfRange();

这将创建一个类OutOfRangethrow的新实例。请记住,您还可以创建这样的实例:

my_method( MyClass() );

而不是:

MyClass obj; 
my_method( obj );

现在:

catch (IntRange::OutOfRange)

OutOfRangeIntRange内部或嵌套类。见here

答案 1 :(得分: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)

避免与切片作为异常层次结构一部分的对象相关的问题。

答案 2 :(得分:0)

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

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

try
{
    //do something
}
catch (OutOfRange o)
{
    //you know the input was out of range
}
catch (Exception e)
{
    //something else went wrong
}

答案 3 :(得分:0)

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

为了使用OutOfRange,即使IntRange实际上可以作为具体类使用也没有要求,因为IntRange::OutOfRange只是指定了完全限定的类型名而不是对象。 / p>

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