C ++如何处理错误出现在对象组合深处?

时间:2014-03-10 22:51:48

标签: c++ exception

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

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;  
}

2 个答案:

答案 0 :(得分:2)

我可以想到以下方法来处理函数深层次的错误 - 它们是由对象组合还是由函数层组成而不相关。

方法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;  
}

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

如果你有指向本地对象的指针,并且指针的寿命可能超过指向的对象,那么你的做法非常简单。这样的设计是崩溃的秘诀。