English 中文(简体)
如何在现实世界中使用沉积、尝试{}捕获?
原标题:How throw, try {} catch {} should be used in the real world?

I mean, I knew all the language rules about throw, try {} catch {}, but I am not sure if I am using them correctly in the real world. Please see the following example:

我们有一大批科学法典,它处理各种图像,我们最近决定予以采纳,使之更加有力。 经常使用的一种例行做法是 避免在_place(float*形象、形象_size sz)上轮流使用;

为了使其更加有力,我们在守则的开头增加了一些桑性检查:

void rotate_in_place(float* image, image_size sz) {
    // rotate_in_place does not support non-square image;
    if (sz.nx != sz.ny)  throw NonSquareImageError;
    // rotate_in_place does not support image too small or too large
    if (sz.nx <= 2 || sz.nx > 1024)  throw WrongImageSizeError;
    // Real rode here
    .....
}

现在的问题是,在1 000多个地点使用轮值_in_place()时,我应总结每一次轮值_in_place()和Creet{}的轮值,这样,我就认为,密码会令人难以置信。 另一种可能性不是包罗任何试样子,而是让方案退出,而是这种方式不同于仅仅使用方案。

if (sz.nx != sz.ny) {
    cerr << "Error: non-squared image error!
";
    exit(0);
}

简言之,我不敢肯定使用 throw、审判、捕获和任何良好建议的真正好处?

最佳回答

处理错误需要的每个网站try -> 副渔获物/编码>。 这一切都取决于你的设计,但我怀疑你需要处理每条<代码>的错误。 大部分时间,你可能不再传播。

印刷错误和使用<代码>exit是坏的,原因有三:

  1. You can t handle the error. exit is not handling (unless it s done when the error is absolutely critical, but your function cannot know that — caller might have a way to recover).
  2. You re extending responsibilities of the function with writing to a hard-coded stream, which might not even be available (this is rotate_in_place, not rotate_in_place_and_print_errors_and_kill_the_program_if_something_is_wrong) — this hurts reusability.
  3. You lose all debugging information with this approach (you can generate stack traces from unhandled exceptions, you can t do anything with a function that bails out every time — unhandled exception is a bug, but it s a bug you can follow to the source).
问题回答

例外的一般规则是,“立即打电话的现场看看一下这里的情况?” 如果电话站确实提供护理,那么恢复身份法可能具有意义。 否则,扔.就更有意义。

相信这种方式——肯定是,您轮流使用的方法有两种无效的理由类型,在这种情况下,你可能要扔下<条码>:invalid_argument<>。 “rotate_in_place”的打电话者不大可能要处理或知道如何处理某一形象不是平方的情况,例如,这种形象可能最好作为一种例外表述。

Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using

if (sz.nx != sz.ny) {
    cerr << "Error: non-squared image error!
";
    exit(0);
}

这有其不同之处,因为如果有人后来想行使职能,并把它列入“全球倡议”的申请,他们就不必根据错误终止该方案。 它们可将这一例外变成对使用者或类似用户的某种例外。

现在也给你带来好处,即:你不必把<条码>和>;“

我通常采用这样的模式:

int realEntryPoint()
{
    //Program goes here
}

int main()
{
    //Allow the debugger to get the exception if this is a debug binary
    #ifdef NDEBUG
    try
    #endif
    {
      return realEntryPoint();
    }
    #ifdef NDEBUG
    catch (std::exception& ex)
    {
      std::cerr << "An exception was thrown: " << ex.what() << std::endl;
    }
    #endif
}

现在的问题是,在1 000多个地方使用轮换制(in_place())时,我应总结每一次使用rotate_in_place(<> with try{}的电话。

它将首先确定使用例外情况的目的。

另一种可能性不是包罗任何试卷{},而是让方案退出,而是这不同于仅仅使用[......]。

That you can always change the location of exception handling later on. If at some point you find a better place to sensibly handle the error (perhaps recovering from it), then that s the point where you put the catch. Sometimes that s in the very function where you throw the exception; sometimes it s way up in the call chain.

Do put a catch-all in main, just in case. Deriving exceptions from standard ones such as std::runtime_error makes doing this a lot easier.

The point in using exception handling holds in following simple rules:

  • As soon as anything bad can happen due to bad user input (internal logic should be handled via assertions/logging), throw an exception. Throw as soon as possible, and as much as possible: C++ exceptions are usually pretty cheap compared to say, .Net ones.
  • Let an exception propagate if you can t handle the error. This means pretty much always.

记住的是:例外情况应当到可以处理的地步。 这可能意味着带有某种错误格式的方言盒,或这可能意味着,一些未进口的逻辑在全部之后就被执行。

采用例外规定,可选择查询器/strong>来决定如何处理错误。 如果你在职能范围内直接打电话到<代码>exit,那么,如果打电话者无法决定如何处理错误,方案就会退出。 另外,通过<代码>exit,中标物体不会被打。

What you can do is to make rotate_in_place return a boolean if the function call was succesfull. And return the rotated image via a function parameter.

bool rotate_in_place(float* image, image_size sz, float** rotated_image) {
    // rotate_in_place does not support non-square image;
    if (sz.nx != sz.ny)  return false;
    // rotate_in_place does not support image too small or too large
    if (sz.nx <= 2 || sz.nx > 1024)  return false;
    // Real rode here
    .....
    return true;
}

它取决于。

例外通常意味着被抓/处理。 在你的情况下,可以处理例外情况(例如,用户提供非总部形象,请他们再次尝试)。 然而,如果你无法做到这一点,那么cerr是行走的道路。

我完全同意,使用例外实际上会导致支离破碎的代码。 这是我不喜欢的主要原因。

例如: 放弃例外和仅仅使用退出()之间的主要区别是,由于处理例外情况发生在(或本应发生)方案碎片之外,从而产生错误/例外,你没有具体说明职能/职等使用者如何处理错误。 通过使用例外,你允许采用不同的处理方法,如流产、报告错误或甚至从某些错误中恢复。

TLDNR: If you use exceptions, the exception-generating part of the code does not need to specify how the exceptional case is treated. That happens in the outside program and can be changed depending on how the code is being used.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?