【问题标题】:Throw catch in namespaces implementation在命名空间实现中抛出 catch
【发布时间】:2016-03-02 21:38:12
【问题描述】:

我正在尝试使用命名空间实现除法程序。我真的很困惑该怎么做,因为任务的范围非常广泛。谁能看一下代码并解释为什么我的 throw, catch 语句不会捕获非整数字符。

分母等于0时抛出异常,但输入字符时不抛出异常。例如,当我输入“abc”时程序崩溃。有人也可以解释一下命名空间吗?谢谢

我应该使用指针吗?...

命名空间文件:

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

namespace dataChecks
{
  /*
   * parameter numerator
   * parameter denominator
   * returns the double quotient of integer division
   * throws an exception if denominator == 0
   */
 //  bool isvalidInt(string str)


  double quotient( int numerator, int denominator)
  {
     if(denominator == 0)
      throw new string("divide by zero!");
     return static_cast<double>(numerator)/denominator;
   }//end quotient()


  /*
   * parameter str  - the string to evaluate
   * returns true if the string can be parsed
   *   into a valid int
   */
   bool isvalidInt(string str)
   {
     int start = 0;
     int i; //index of one character in the string
     bool valid = true;  // assume a valid string
     bool sign = false;  // assume no sign

     if (str.length()==0)    // if the length of the string is 0
         {
        valid = false;      //set valid to false
        }

     if ((str.at(0) == '+')||(str.at(0) == '-'))  // if the first character is '-' or '+'
     {
         sign = true;
         start= 1;      //set sign to true and start to 1
     }
if ((start && str.length()) == 1)  // if there is not at least one character after the sign
    {
        valid = false;  //set valid to false
    }
i = start;
while( i < str.length() )// check if each character in the string is a digit - isdigit(str.at(i))
    {
        if (isdigit(str.at(i)) == false)
        {
            valid = false;      // if a character is not a digit, set valid to false
        } i++;       // return valid;
    }
return valid;
  }

   /*
    * gets a string from the keyboard
    * throws an exception if the string cannot
    *   be parsed into a valid int
    * otherwise returns the int represented by the string
    */

   int getAnInt()
  {
bool notanint = true;
string svalue;

while (notanint)
{
  try
  {
    // get a string from the
    cin >> svalue;
    // if it is not a valid int throw an exception]

    if (isvalidInt(string (svalue)) == false) throw svalue;
  }
  catch (string e)
  {

    cout<< "Invalid integer [ " << e << " ] - Please reenter: \t";
    // print an error messagecout << "Invalid integer [ " << e << " ] - Please reenter: ";
        continue;
    // send control back to the while statement
  }
  notanint = false;
}
return atoi(svalue.c_str());  // convert to an integer
   }

测试文件:

/*
 * CSIS1600
 * checkDivisionDemo.cpp
 * divide by zero exception
 * uses personal namespace dataChecks
 */

 #include <C:\\CSIS1600\\MyCPPUtils\\dataChecksNamespace.cpp>
 #include <iostream>

 using namespace dataChecks;
 using namespace std;

int main()
{
   int number1; // user-specified numerator
   int number2; // user-specified denominator

   cout << "Enter two integers (end-of-file to end): ";

   // enable user to enter two integers to
    while ( cin >> number1 >> number2 )
    {
  // try block contains code that might throw exception
  // and code that will not execute if an exception occurs
  try
  {
     double result = quotient( number1, number2 );
     cout << "The quotient is: " << result << endl;
  } // end try
  catch ( string *str )
  {
     cout << "Exception occurred: "
        << *str << endl;
  } // end catch
 //     try
 //    {
 //        bool validint1 = isvalidInt(number1, number2);
 //    }
 //     catch ()
       cout << "\nEnter two integers (end-of-file to end): ";
    } // end while

   cout << endl;
 } // end main

【问题讨论】:

  • 以供将来在 stackoverflow.com 上发布问题时参考: 1. 正确格式化您的代码。 2. 排除不相关的东西。

标签: c++ namespaces try-catch division throw


【解决方案1】:

在 C++ 中使用异常的黄金法则是“按值抛出,按常量引用捕获”。

quotient(),当你说

throw new string("divide by zero!");

您正在堆上创建一个新字符串,如果发生异常,该字符串永远不会被释放。相反,你应该说

throw string("divide by zero!");

它将堆栈分配一个新字符串。

稍后,在你的 catch 块中,你应该通过 const 引用来捕捉,即

catch (const string& str) {
    // ...
}

这样做的原因主要是技术性的:const 引用可以绑定到右值,而可变引用不能,并且按值捕获可能需要字符串的副本。

或者换个角度看:异常的目的是传达某事失败的原因。这个原因一旦发生就不会改变,所以创建后应该将异常处理为const

【讨论】:

  • 我听从了你的建议,它使程序崩溃了,我想抛出的异常没有遵循。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
相关资源
最近更新 更多