草庐IT

具有精心设计的异常机制的 C++ 项目

coder 2024-02-04 原文

有谁知 Prop 有设计良好/强大的异常机制的开源 C++ 应用程序,以便我获得一些灵感?我看到的大多数代码/示例都会做一些有问题的事情,例如:

  1. 以消息字符串作为参数抛出对象。似乎是错误的,因为它将异常标记为致命异常,可以向更高层的用户显示的错误消息为尝试处理异常的客户端代码留下了很小的空间。即使异常是致命的,不同的语言环境(语言)之类的事情也会让在抛出点格式化消息对我来说似乎是个坏主意。
  2. 使用大量派生自异常基类的不同异常类。为每一件可能出错的事情(打开文件、读取文件、写入文件、创建线程等)引入一个新的类/类型感觉不对。使用基本类型在最高级别捕获所有未处理的异常会丢失显示有意义的错误消息所需的类型信息。
  3. 为每个组件/库使用一个派生自异常基类的异常类,并为其提供一个错误代码作为参数以指示确切的错误。捕获基类型会导致歧义。 (我们捕获了谁的错误代码“3”?)...

一些正确方向的指示将受到欢迎。

最佳答案

为了解决所有这三个问题,我发现对我来说最好的方法是抛出我自己的派生自 std::runtime_error 的自定义异常。像这样:

#include <exception>

class ChrisAException : public std::runtime_error
{
      /// constructor only which passes message to base class
      ChrisAException(std::string msg)
      : std::runtime_error(msg)
      {

      }
}

它允许接受一个字符串,我总是把它放在类似下面的格式中(假设 x negative 不是一个有效的输入并且意味着调用它的东西是错误的):

#include "ChrisAException.h"

void myfunction(int x)
{

    if(x < 0) 
    {
        throw ChrisAException("myfunction(): input was negative!");
    }

    // rest of your function
} 

对于这一个,请记住这些异常中的字符串更多是为程序员而不是最终用户提供的。当出现故障时,界面的程序员的工作是在语言环境中显示一些有意义的东西。异常中的字符串可以在调试时记录或查看(最好!)

这样你就可以最终捕获它:

try
{
      // high level code ultimately calling myfunction

}
catch(ChrisAException &cae)
{
       // then log cae.what()
}
catch(std::runtime_error &e)
{
       // this will also catch ChrisAException's if the above block wasn't there
}
catch(...)
{
      // caught something unknown
}

我个人不喜欢导出太多类型的异常,或者给出错误代码。我让字符串消息进行报告。

一般来说,我使用 C++ 异常来表示“程序出了点问题”,不是来处理正常用例。因此,对我来说,算法执行期间抛出的异常要么意味着“标记用户出了问题”要么“不告诉用户”(取决于代码对他们所做的事情的重要性)但肯定会记录它并以某种方式让程序员知道。

我不使用 C++ 异常来处理本质上不是编程错误的情况,例如,某种不正确的逻辑或被称为错误的东西。例如,我不会使用 C++ 异常来处理正常的程序情况,例如空 DVD 不在 DVD 写入程序的驱动器中。为此,我有明确的返回代码,允许用户知道那里是否有空 DVD(可能带有对话框等)

请记住,C++ 异常处理的一部分是将堆栈展开到 try-catch block 。对我来说,这意味着中止程序中正在发生的事情并清理堆栈。在像我的 DVD 示例这样的情况下,您不应该真的想要展开很多堆栈。这不是灾难性的。您应该简单地让用户知道,然后让他们重试。

但是,根据我的经验和阅读,这是我使用 C++ 异常的首选方式。我对其他意见持开放态度。

编辑:根据评论者的建议将 std::exception 更改为 std::runtime_error

关于具有精心设计的异常机制的 C++ 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10325330/

有关具有精心设计的异常机制的 C++ 项目的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  6. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  7. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  8. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  9. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  10. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

随机推荐