好的,我必须在单独的答案帖子中添加对您提出的观点的答案:(如果您将其编辑到原始问题中会更方便,因此它不会出现在下面的底部答案。
如果所有清理总是在析构函数中完成,那么在 catch 块中就不需要任何清理代码 - 但是 C++ 有可以在其中完成清理操作的 catch 块。事实上,它有一个用于 catch(...) 的块,它只能执行清理操作(当然,不能获取任何异常信息来执行任何日志记录)。
catch 有一个完全不同的目的,作为一名 Java 程序员,您应该意识到这一点。finally 子句用于“无条件”清理操作。无论块如何退出,都必须这样做。Catch 用于条件清理。如果抛出这种类型的异常,我们需要执行一些额外的操作。
无论是否抛出异常,finally 块中的清理都将完成——这是当清理代码确实存在时人们总是希望发生的事情。
真的吗?如果我们希望这种类型总是发生这种情况(例如,我们总是想在完成后关闭数据库连接),那么我们为什么不定义一次呢?在类型本身?使数据库连接自行关闭,而不是在每次使用它时都尝试/最终?
这就是析构函数的重点。他们保证每种类型都能够在每次使用时自行进行清理,而无需调用者考虑。
从第一天开始,C++ 开发人员就不得不重复出现在代码流中的 catch 块中的清理操作,这些操作在成功退出 try 块时发生。Java 和 C# 程序员只需在 finally 块中执行一次。
不会。C++ 程序员从来没有被这个困扰过。C程序员有。C 程序员意识到 c++ 有类,然后称自己为 C++ 程序员。
我每天都用 C++ 和 C# 编程,我觉得我被 C# 荒谬的坚持所困扰,我using
每次使用数据库连接或其他必须清理的东西时都必须提供 finally 子句(或块)。
C++ 让我一劳永逸地指定“只要我们完成了这种类型,它就应该执行这些操作”。我不会冒险忘记释放内存。我不会冒险忘记关闭文件句柄、套接字或数据库连接。因为我的记忆、我的句柄、套接字和数据库连接都是自己做的。
每次使用类型时都必须编写重复的清理代码,这怎么能更好呢?如果您需要包装类型,因为它本身没有析构函数,您有两个简单的选择:
- 寻找提供此析构函数的适当 C++ 库(提示:Boost)
- 使用 boost::shared_ptr 来包装它,并在运行时为它提供一个自定义函子,指定要完成的清理工作。
当您编写 Java EE 应用服务器 Glassfish、JBoss 等应用服务器软件时,您希望能够捕获并记录异常信息——而不是让它掉在地上。或者更糟糕的是陷入运行时并导致应用程序服务器突然退出。这就是为什么对于任何可能的异常都有一个总体基类是非常可取的。而 C++ 就是这样一个类。标准::异常。
自 CFront 时代以来,我一直在做 C++,在这十年的大部分时间里都在做 Java/C#。很明显,在处理基本相似的事情方面存在巨大的文化差距。
不,你从来没有做过 C++。你已经完成了 CFront 或 C 类。不是 C++。有很大的不同。不要说答案是蹩脚的,你可能会学到一些你认为你知道的语言。;)