In C++ what are the benefits of using exceptions a

2020-01-30 05:39发布

I've programmed C and C++ for a long time and so far I've never used exceptions and try / catch. What are the benefits of using that instead of just having functions return error codes?

13条回答
你好瞎i
2楼-- · 2020-01-30 06:04

Exception handling is useful because it makes it easy to separate the error handling code from the code written to handle the function of the program. This makes reading and writing the code easier.

查看更多
走好不送
3楼-- · 2020-01-30 06:05

Here's a good explanation of EAFP ("Easier to Ask for Forgiveness than Permission."), which I think applies here even if it's a Python page in Wikipedia. Using exceptions leads to a more natural style of coding, IMO -- and in the opinion of many others, too.

查看更多
Viruses.
4楼-- · 2020-01-30 06:06
  • return an error code when an error condition is expected in some cases
  • throw an exception when an error condition is not expected in any cases

in the former case the caller of the function must check the error code for the expected failure; in the latter case the exception can be handled by any caller up the stack (or the default handler) as is appropriate

查看更多
啃猪蹄的小仙女
5楼-- · 2020-01-30 06:08

Google's C++ Style Guide has a great, thorough analysis of the pros and cons of exception use in C++ code. It also indicates some of the larger questions you should be asking; i.e. do I intend to distribute my code to others (who may have difficulty integrating with an exception-enabled code base)?

查看更多
够拽才男人
6楼-- · 2020-01-30 06:12

As @Martin pointed out throwing exceptions forces the programmer to handle the error. For example, not checking return codes is one of the biggest sources of security holes in C programs. Exceptions make sure that you handle the error (hopefully) and provide some kind of recover path for your program. And if you choose to ignore an exception rather than introduce a security hole your program crashes.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2020-01-30 06:16

The advantage is that you don't have to check the error code after each potentially failing call. In order for this to work though, you need to combine it with RAII classes so that everything gets automatically cleaned up as the stack unwinds.

With error messages:

int DoSomeThings()
{
    int error = 0;
    HandleA hA;
    error = CreateAObject(&ha);
    if (error)
       goto cleanUpFailedA;

    HandleB hB;
    error = CreateBObjectWithA(hA, &hB);
    if (error)
       goto cleanUpFailedB;

    HandleC hC;
    error = CreateCObjectWithA(hB, &hC);
    if (error)
       goto cleanUpFailedC;

    ...

    cleanUpFailedC:
       DeleteCObject(hC);
    cleanUpFailedB:
       DeleteBObject(hB);
    cleanUpFailedA:
       DeleteAObject(hA);

    return error;
}

With Exceptions and RAII

void DoSomeThings()
{
    RAIIHandleA hA = CreateAObject();
    RAIIHandleB hB = CreateBObjectWithA(hA);
    RAIIHandleC hC = CreateCObjectWithB(hB);
    ...
}

struct RAIIHandleA
{
    HandleA Handle;
    RAIIHandleA(HandleA handle) : Handle(handle) {}
    ~RAIIHandleA() { DeleteAObject(Handle); }
}
...

On first glance, the RAII/Exceptions version seems longer, until you realize that the cleanup code needs to be written only once (and there are ways to simplify that). But the second version of DoSomeThings is much clearer and maintainable.

DO NOT try and use exceptions in C++ without the RAII idiom, as you will leak resources and memory. All your cleanup needs to be done in destructors of stack-allocated objects.

I realize there are other ways to do the error code handling, but they all end up looking somewhat the same. If you drop the gotos, you end up repeating clean up code.

One point for error codes, is that they make it obvious where things can fail, and how they can fail. In the above code, you write it with the assumption that things are not going to fail (but if they do, you'll be protected by the RAII wrappers). But you end up paying less heed to where things can go wrong.

查看更多
登录 后发表回答