[英]C++ - Where to throw exception?
我有某种意识形态问题,所以:
假设我有一些模板化的功能
template <typename Stream>
void Foo(Stream& stream, Object& object) { ... }
它对这个object
和stream
做了一些事情(例如,将该对象序列化为流或类似的东西)。
假设我也添加了一些简单的包装器(并且假设这些包装器的数量等于2或3):
void FooToFile(const std::string& filename, Object& object)
{
std::ifstream stream(filename.c_str());
Foo(stream, object);
}
所以,我的问题是:
在这种情况下(在意识形态上),如果我的stream
不好,我应该抛出异常吗? 我应该在每个包装器中执行此操作,还是将该检查移动到我的Foo
,以便它的主体看起来像
if (!foo.good()) throw (something);
// Perform ordinary actions
我知道这可能不是编码中最重要的部分,这些解决方案实际上是相同的,但我只是不知道“正确”的方法来实现它。
谢谢。
在这种情况下,最好将它放在较低级别的Foo
函数中,这样就不必在所有包装器中复制验证和异常抛出代码。 通常,正确使用异常可以通过删除大量数据验证检查来使代码更加清晰,否则您可能会在调用堆栈中的多个级别进行冗余操作。
我宁愿不延迟通知错误。 如果你知道在创建了流之后,那就不好了,为什么要调用一个适合它的方法呢? 我知道为了减少代码冗余,你计划进一步降低代码冗余。 但该方法的缺点是一个不太具体的错误消息。 所以这在某种程度上取决于源代码上下文。 如果您可以在较低功能级别获得通用错误消息,则可以在其中添加代码,这肯定会简化代码的维护,尤其是当团队中有新的开发人员时。 如果您需要特定的错误消息,请在故障点处更好地处理它。
为避免代码冗余,请调用一个常见函数,为您生成此异常/错误。 不要在每个包装器中复制/粘贴代码。
你越早发现异常就越好。 异常越具体 - 越好。 除了声明之外,不要害怕将大部分代码包含在try catch块中。
例如:
int count = 0;
bool isTrue = false;
MyCustomerObject someObject = null;
try
{
// Initialise count, isTrue, someObject. Process.
}
catch(SpecificException e)
{
// Handle and throw up the stack. You don't want to lose the exception.
}
我喜欢使用辅助函数:
struct StreamException : std::runtime_error
{
StreamException(const std::string& s) : std::runtime_error(s) { }
virtual ~StreamException() throw() { }
};
void EnsureStreamIsGood(const std::ios& s)
{
if (!s.good()) { throw StreamException(); }
}
void EnsureStreamNotFail(const std::ios& s)
{
if (s.fail()) { throw StreamException(); }
}
如果我不期望失败,我会在执行流操作之前和之后立即测试它们。
传统上,在C ++中,流操作不会抛出异常。 这部分是出于历史原因,部分原因是流量故障是预期的错误。 C ++标准流类处理此问题的方法是在流上设置一个标志,以指示发生了错误,用户代码可以检查。 不使用异常使得恢复(流式操作通常需要恢复)比抛出异常更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.