繁体   English   中英

C ++ - 在哪里抛出异常?

[英]C++ - Where to throw exception?

我有某种意识形态问题,所以:

假设我有一些模板化的功能

template <typename Stream>
void Foo(Stream& stream, Object& object) { ... }

它对这个objectstream做了一些事情(例如,将该对象序列化为流或类似的东西)。

假设我也添加了一些简单的包装器(并且假设这些包装器的数量等于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM