安全过载流运算符>>(Safely overloading stream operato

2019-08-01 07:34发布

有超载提供大量信息operator<<模仿toString()风格的一个复杂的对象转换为字符串的方法。 我很感兴趣, 实施逆, operator>>反序列化字符串转换成一个对象。

通过检查STL源,我收集的是:

istream &operator>>(istream &, Object &);

将是反序列化类型的对象正确的函数签名Object 。 不幸的是,我一直在为如何正确地实现这样的损失 - 特别是如何处理错误:

  1. 如何指示流中的无效数据? 抛出一个异常?
  2. 应流是如果流中畸形数据是什么状态?
  3. 如果任何标志返回为运营商链接引用之前被复位?

Answer 1:

  1. 如何指示流中的无效数据? 抛出一个异常?

您应该设置fail位。 如果流的用户希望被抛出的异常,他可以配置流(使用istream::exceptions ),并且流将相应地抛出。 我会做这样的话

stream.setstate(ios_base::failbit);
  1. 应流是如果流中畸形数据是什么状态?

对于不适合你想要阅读的格式畸形数据,你通常应该设置fail位。 对于内部流特定错误时, bad位用于(例如,如果没有连接到流缓存器)。

  1. 如果任何标志返回为运营商链接引用之前被复位?

我没有听说过这样的事情。


为了检查流是否处于良好状态,你可以使用istream::sentry类。 创建它的一个对象,使该气流和true (告诉它不要马上跳过空格)。 哨兵将评估为false ,如果eoffailbad位。

istream::sentry s(stream, true);
if(!s) return stream;
// now, go on extracting data...


Answer 2:

一些补充说明:

  • 执行操作时>>,你或许应该考虑使用bufstream和运营商的不是其他重载>>;

  • 异常操作过程中存在的应该被翻译到failbit或badbit(流缓冲的成员可能抛出,根据所用的类);

  • 设定的状态下可能会抛出; 如果您捕获异常后置的状态,你应该传播原始的异常,而不是一个由setstate这倒掉;

  • 宽度是一个领域,你要注意。 如果你正在考虑它,你应该如果你正在使用其他运营商>>做基础工作,你要计算你所收到的一个路过的宽度重置为0;

  • 考虑采取区域考虑。

兰格和Kreft( 标准C ++输入输出流和语言环境 )中更详细CONVER此。 他们给了错误处理,这需要大约一个页面的模板代码。



Answer 3:

至于标志,我不知道是否有任何标准的地方,但它是将它们重置一个好主意。

升压具有用于整齐RAII包装: IO拯救国家



文章来源: Safely overloading stream operator>>