【问题标题】:c++ std::exception ... may I have more please? [closed]c++ std::exception ...我可以再给我更多吗? [关闭]
【发布时间】:2013-03-03 01:43:12
【问题描述】:

我浏览了http://en.cppreference.com/w/cpp/error/exceptionhttp://en.cppreference.com/w/cpp/io/basic_fstream 寻找我可能抛出的I/O 异常。我知道我可以创建自定义异常类,并且有很多网站提供示例代码,但我想要一些专门针对最佳实践的指导。

另外,有没有我应该专注于使用的图书馆来让我的生活更轻松?

【问题讨论】:

  • 也许你能解释一下这个类似java的实用程序对我们这些不熟悉它的人有什么作用?
  • 不熟悉Java,我不太明白这个问题。除了让你脱离主流之外,异常应该做什么?不同的异常类型使您能够选择捕获哪些异常以及传播哪些异常,但您不需要细粒度的类。
  • @user633658 没有冒犯,但你是从什么经验的角度来看待这个观点的?委员会对建议持开放态度,尽管我觉得还没有资格提出任何建议。委员会必须有充分的理由在 std 库中包含某些内容。
  • 从你的问题和 cmets 来看,这听起来更像是一个咆哮而不是一个问题。当然图书馆可能有更多的例外;更好的?你坚持什么,我们能提供什么帮助?你已经知道你需要创建一个自定义异常类,你需要帮助吗?如果是这样,请放弃希望您不必这样做的潜台词。
  • @user633658 冷静点。我想你惹恼了很多人;您似乎是该语言的新手,并且对该网站相对较新,但您刚刚告诉我们,多年来我们都做错了。 什么是 std::exception 最佳实践? 可能是一个更好的问题。

标签: c++ exception exception-handling c++11 fstream


【解决方案1】:

C++11 为低级错误引入了新的标头 system_error。可以编写自己的错误类别。

这可能是您在现代 C++ 中编写自己的错误处理的良好起点。

【讨论】:

  • 我喜欢这个,并将研究它以制作自定义异常类。
  • +1 是提及system_error 的唯一答案,在这种情况下,这是 IMO 的正确解决方案。
  • @ildjarn 这将是答案,因为他正在引入 c++11 解决方案,我喜欢做新的事情。如果我得到更多建议,我会很乐意将名称切换到此答案。
  • @user633658 : 如果与Boost.System 结合使用,Boost.Exception 是同样合适的答案,并且具有使用 C++03 的额外优势。
  • @ildjarn 那么请帮我指定社区认为代表我所追求的最佳实践的最合适的答案。 en.cppreference.com/w/cpp/error/error_category 是我一直在寻找的东西。
【解决方案2】:

predefined exceptions 有很多,但通常,您要么定义自己的,要么将 std::runtime_error 作为第一个近似值。

通常,您会扩展std::runtime_error,或者更合适的std::exception 的其他派生词。

例如,

class io_error : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

【讨论】:

  • 好主意,我喜欢。我不同意异常库包含“很多”,因为我看到缺少一些异常,并且存在的异常可以简单地修改,因为有些似乎是不必要的。
  • @user633658 哪些是不必要的?我认为它们都在某处的std 库中使用。
  • 例如逻辑错误,它似乎没有那么有用。正如我所写的,Java 在异常方面非常出色。也许是因为他们只是改进了 c++ 开始的一个好主意,我认为 c++ 可以通过他们自己的一些修订来效仿。
  • @user633658 std::logic_error 非常有用。当不满足算法不变量时应该抛出它,例如std::invalid_argument。它们也可以在开发时断言中使用。 std::out_of_rangestd::vector::at 抛出;必须在 Java 中引发类似的异常,据我了解,它总是检查范围错误?
  • @user633658 “Java 在异常方面很漂亮”不,Java 中的异常很糟糕。
【解决方案3】:

要回答问题的图书馆部分,请在boost::exception 联系a look

Boost 异常可以从一个线程转移到另一个线程,并且您可以动态地将信息附加到异常 - 使用 operator<< - 当您捕获(并可选择重新抛出)它时。此外,BOOST_THROW_EXCEPTION 宏会在您的表达式中记录文件、行和函数名称,以便于打印。

否则,通常的做法是为您的项目定义自己的例外。但是很难给出更具体的答案,因为我不熟悉您所说的“类似 java 的实用程序”。

作为一个更一般的说明,C++ 设计原则之一就是做你所要求的,仅此而已,这在某些情况下是一种祝福,在某些情况下意味着更多的工作——这与 java 完全不同。异常的主要目的是用throw/catch 中断正常的程序流程,C++ 就是这样做的。

如果你只想要一个简单的字符串消息:

struct E: std::exception {
  const char* msg;
  E(const char* msg_): msg(msg_) {}
  const char* what() const { return msg; }
};
// ...
throw E("invalid operation name");

【讨论】:

  • Java 之所以被引用是因为其包含完善的异常库。同意 c++ 处理异常,但它们的异常库非常缺乏,我真的不想编写自定义类来处理异常。
  • @user 您的问题和评论都没有清楚地解释您发现 C++ 异常不完整的方式。
  • 根据观点:C++ 的库不如 java 完整 - 或者它不会强迫您设计它的库。这是事实,并且可以说是一个特点。如果您愿意,可以使用 boost::exception 或其他库。此外,使用错误字符串编写一个简单的异常类所需的字符数将少于此注释。
  • @us2012 这是关于编写 c++ 异常类的问题。我以评论开头我的问题,没想到这次讨论会退化为情绪。为了回答您的问题,我认为诸如 logic_error 之类的 c++ 异常已过时,c++ 委员会可以通过添加更多内容来修改它,特别是在 i/o 领域。我不想检查 fstream 对象的状态。不,我只想知道是否发生异常并以 Java 风格的方式处理它。在某些方面,我觉得 c++ 可以使异常更加面向对象。
  • @user633658:我的目的不是冒犯你。对不起,我有点坚强-;) 我觉得你在问为什么 C++ 不是 java,但那样想只会导致沮丧。由于复杂性和向后兼容性,C++ 的某些方面已经过时;它的设计原则与java不同。两种语言都有优势,但是如果您使用 C++ 工作,请不要考虑使用 java。例如,每个异常类型并不总是需要一个类,因为错误类型可能通过其他方式传达(boost::exception 中的任意数据)。
猜你喜欢
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 2015-07-07
  • 2010-12-12
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
相关资源
最近更新 更多