C++如何处理对象组合中出现的错误

C++ how to deal with error appeared deep in objects composition?

本文关键字:组合 错误 对象 何处理 处理 C++      更新时间:2023-10-16

这里每个新方法调用都必须检查错误,这真的。。。至少要慢一点。我在考虑例外情况,但我读到它们不适合处理错误。例如,如果我要抛出异常,我必须使用堆栈上的上一个方法来处理它,因为否则可能会有局部变量指向该方法中分配的空间,所以我不能跳过它。那么,有什么好的方法吗?

class A {
  int method() {
     ...; 
     return 1;
  }
};
class B {
  A a;
  int method() {
    int err = a.method();
     if (err == 1) {
       ...;
       return ret;
     }
  }
};
class C {
  B b;
  int method() {
     int err = b.method();
     if (err == 1) {
       ...;
       return ret;
     }
   }
};
int main() {
  C c;
  int err = c.method();
  if (err == 1) {}
  return 0;  
}

我可以想出以下方法来处理函数中深层的错误——无论它们是由对象组合还是函数层引起的,都是不相关的。

方法1:在低级别函数的深处抛出异常

struct my_error_A {};
class A {
  void method() {
      if ( ... )
      {
         throw my_error_A();
      }
     ...; 
  }
};
struct my_error_B {};
class B {
  A a;
  void method() {
    a.method();
       ...;
      if ( ... )
      {
         throw my_error_B();
      }
  }
};
struct my_error_C {};
class C {
  B b;
  void method() {
     b.method();
       ...;
      if ( ... )
      {
         throw my_error_C();
      }
   }
};
int main() {
  C c;
  try
  {
     c.method();
  }
  catch (my_error_A err)
  {
     // Deal with errors from A.
  }
  catch (my_error_B err)
  {
     // Deal with errors from B.
  }
  catch (my_error_C err)
  {
     // Deal with errors from C.
  }
  catch (...)
  {
     // Deal with all othe exceptions.
  }
  return 0;  
}

方法2:使用全局错误代码保持器来跟踪错误

int globalErrorCode = 0;
class A {
    void method() {
        a.method();
        ...;
        if ( ... )
        {
           globalErrorCode = A::errorCode;
        }
    }
  static int errorCode;
};
class B {
  A a;
  void method() {
      a.method();
      if ( globalErrorCode != 0 )
      {
         return;
      }
      ...;
      if ( ... )
      {
         globalErrorCode = B::error_code;
         return;
      }
      ...;
  }
  static int errorCode;
};
class C {
  B b;
  void method() {
      b.method();
      if ( globalErrorCode != 0 )
      {
         return;
      }
      ...;
      if ( ... )
      {
         globalErrorCode = C::error_code;
         return;
      }
      ...;
  }
  static int errorCode;
};
int main() {
  C c;
  c.method();
  if ( globalErrorCode != 0 )
  {
     // Deal with error code.
  }
  return 0;  
}

方法3:在每个级别返回错误代码,并在每个级别进行处理

class A {
  int method() {
      if ( ... )
      {
         return A::errorCode;
      }
     ...; 
  }
  static int errorCode;
};
class B {
  A a;
  int method() {
      int err = a.method();
      if ( err != 0 )
      {
         return err;
      }
      ...;
      if ( ... )
      {
         return B::errorCode;
      }
  }
  static int errorCode;
};
class C {
    B b;
    int method() {
        int err = b.method();
        if ( err != 0 )
        {
           return err;
        }
        ...;
        if ( ... )
        {
           return C::errorCode;
        }
    }
    static int errorCode;
};
int main() {
  C c;
  int err = c.method();
  if ( err != 0 )
  {
     // Deal with errors
  }
  return 0;  
}
class A
{   void method()
    {
    }
};
class B
{   A a;
    void method()
    {   a.method();
    }
};
class C
{   B b;
    void method()
    {   b.method();
    }
};
int main()
{   try
    {   C c;
        c.method();
        return 0;
    } catch (const std::exception &e)
    {   std::cerr << "Failure: " << e.what() << std::endl;
        return 1;
    }
}

如果你有指向本地对象的指针,而指针的寿命可能比指向的对象长,那么你做的事情就大错特错了。这样的设计会导致崩溃。