C++ 插入>&燃气轮机;运算符重载:检索对象时的异常处理';来自cin的s-ctor参数

C++ 插入>&燃气轮机;运算符重载:检索对象时的异常处理';来自cin的s-ctor参数,c++,constructor,exception-handling,operator-overloading,istream,C++,Constructor,Exception Handling,Operator Overloading,Istream,以下是被认为有效的可能用户输入示例: (-12.444,34.55) (2.0,-44.4444) 。。。无效输入,)丢失: (23.33,-234.5555 (-23.33, 44.1) Complex.cpp:ctor Complex.cpp:异常类 插入运算符重载: Main.cpp:try/catch: 复合体A、B;//创建复杂对象: //我的问题是关于try块中的级联对象 cout>A>>B; } 捕获(常量无效\模式1 \复杂\值和无效模式1异常) { 瑟尔 如果读取对象A

以下是被认为有效的可能用户输入示例:

(-12.444,34.55) (2.0,-44.4444)

。。。无效输入,
丢失:

(23.33,-234.5555 (-23.33, 44.1)

Complex.cpp:ctor Complex.cpp:异常类 插入运算符重载: Main.cpp:try/catch:
复合体A、B;//创建复杂对象:
//我的问题是关于try块中的级联对象
cout>A>>B;
}
捕获(常量无效\模式1 \复杂\值和无效模式1异常)
{
瑟尔
  • 如果读取对象
    A
    引发异常,
    A
    处于某种未知状态,
    B
    保持不变

  • 如果读取对象
    A
    成功,但读取对象
    B
    引发异常,
    A
    处于良好状态,
    B
    处于未知状态

  • 错误的格式是引发异常的地方。但是,如果不能读取
    double
    s,则流中会留下一些部分,读取格式将失败

  • 您应该在读取每个
    double
    后添加流状态检查,以检查是否成功:

    input >> obj.real_part;
    if (!input) throw Invalid_Mode1_Complex_Value();
    
    您应该继续阅读。在这里,您可以通过读取一些局部变量,然后仅在读取成功的情况下将其分配到
    obj
    中,从而在
    复杂
    上提供强异常安全性。(您仍然只在流上提供基本异常安全性)


    您的问题是关于抛出异常后对象的状态是什么,还是关于如何正确处理异常?我最感兴趣的是对象的状态以及编译器如何准确处理这些对象和状态。谢谢bob,非常全面和有用的回答。澄清了我的所有问题!
    class Invalid_Mode1_Complex_Value: public std::invalid_argument {
    
    public:
      Invalid_Mode1_Complex_Value():std::invalid_argument("Invalid value for inputting Complex # using Mode 1"){}
    };
    
    istream & operator >> (istream & input, Complex & obj) {
    
      input.ignore(2,'('); // skip over '('
    
      input >> obj.real_part; // read the real component of the Complex #
    
      // Process ','
      if (input.peek() == ',') {
        input.get(); // swallow ','
      }
      else {
    
        input.flags(origFormat); // restore format flags
    
        input.clear();
    
        throw Invalid_Mode1_Complex_Value();
      }
    
      // Process imaginary part
    
      // read the imaginary component of the Complex #
      input >> obj.imaginary_part;
    
      // Process ')'
      if (input.peek() == ')') {
        input.get(); // swallow ')'
      }
    
      else {
    
        input.flags(origFormat); // restore format flags
    
        input.clear();
    
        throw Invalid_Mode1_Complex_Value();
        }
    
      }
      // restore format flags
      input.flags(origFormat);
    
      return input; // enables  cin >> a >> b >> c
    }
    
    Complex A,B; // Create Complex objects: 
    
    // My question is regarding the cascading objects in the try block
    
    cout << "\nEnter 2 Complex numbers in the form \"(real_value,imaginary_value)\" :\n";
    try     
    {
      cin >> A >> B;
    }
    catch(const Invalid_Mode1_Complex_Value & invalidMode1Exception) 
    {
      cerr << "\nException occurred: " << invalidMode1Exception.what() << endl;
    }
    
    input >> obj.real_part;
    if (!input) throw Invalid_Mode1_Complex_Value();
    
    std::stream& operator>> (std::istream& input, Complex& obj) {
        Complex tmp;
    
        // ...
        input >> tmp.real_part;
        if (!input) throw //...
        // ...
    
        obj = tmp; // if we got to here, we know tmp is properly formed
        return input;
    }