Is there a favored idiom for mimicing Java's try/finally in C++?

前端 未结 15 809
无人及你
无人及你 2021-02-05 19:16

Been doing Java for number of years so haven\'t been tracking C++. Has finally clause been added to C++ exception handling in the language definition?<

15条回答
  •  逝去的感伤
    2021-02-05 19:38

    Ok, I have to add in an answer to the points you made in a separate answer post: (It would be a lot more convenient if you'd edited this into the original question, so it doesn't end up at the bottom below the answers to it.

    If all cleanup always gets done in destructors then there wouldn't need to be any cleanup code in a catch block - yet C++ has catch blocks where cleanup actions get done. Indeed it has a block for catch(...) where it is only possible to do cleanup actions (well, certainly can't get at any exception information to do any logging).

    catch has a completely separate purpose, and as a Java programmer you should be aware of that. The finally clause is for "unconditional" cleanup actions. No matter how the block is exited, this must be done. Catch is for conditional cleanup. If this type of exception is thrown, we need to perform a few extra actions.

    The cleanup in a finally block will get done whether there was an exception thrown or not - which is what one always wants to happen when cleanup code does exist.

    Really? If we want it to always happen for this type (say, we always want to close a database connection when we're done with it), then why don't we define it once? In the type itself? Make the database connection close itself, rather than having to put a try/finally around every single use of it?

    That's the point in destructors. They guarantee that each type is able to take care of its own cleanup, every time it's used, without the caller having to think of it.

    C++ developers from day one have been plagued with having to repeat cleanup actions that appear in catch blocks in the code flow that occurs upon successful exit from the try block. Java and C# programmers just do it once in the finally block.

    No. C++ programmers have never been plagued by that. C programmers have. And C programmers who realized that c++ had classes, and then called themselves C++ programmers have.

    I program in C++ and C# daily, and I feel I'm plagued by C#'s ridiculous insistence that I must supply a finally clause (or a using block) EVERY SINGLE TIME I use a database connection or something else that must be cleaned up.

    C++ lets me specify once and for all that "whenever we're done with this type, it should perform these actions". I don't risk forgetting to release memory. I don't risk forgetting to close file handles, sockets or database connections. Because my memory, my handles, sockets and db connections do it themselves.

    How can it ever be preferable to have to write duplicate cleanup code every time you use a type? If you need to wrap the type because it doesn't have a destructor itself, you have two easy options:

    • Look for a proper C++ library which provides this destructor (hint: Boost)
    • Use boost::shared_ptr to wrap it, and supply it with a custom functor at runtime, specifying the cleanup to be done.

    When you write application server software like Java EE app servers Glassfish, JBoss, etc., you want to be able to catch and log exception information - as opposed to let it fall on the floor. Or worse fall into the runtime and cause a ungraceful abrupt exit of the application server. That's why it's very desirable to have an overarching base class for any possible exception. And C++ has just such a class. std::exception.

    Have done C++ since the CFront days and Java/C# most of this decade. Is clear to see there's just an enormous culture gap in how fundamentally similar things are approached.

    No, you've never done C++. You've done CFront, or C with classes. Not C++. There's a huge difference. Quit calling the answers lame, and you might learn something about the language you thought you knew. ;)

提交回复
热议问题