安全地重载流运营商>>

Mic*_*val 15 c++ operator-overloading stream

有大量关于重载的信息可以operator<<模仿toString()将复杂对象转换为字符串的a- style方法.我很感兴趣,实施反,operator>>反序列化字符串转换成一个对象.

通过检查STL来源,我收集了:

istream &operator>>(istream &, Object &);
Run Code Online (Sandbox Code Playgroud)

将是反序列化类型对象的正确函数签名Object.不幸的是,我对如何正确实现这一点感到茫然 - 特别是如何处理错误:

  1. 如何在流中指示无效数据?抛出异常?
  2. 应流是,如果有什么状态流中的畸形数据?
  3. 在返回操作符链接的引用之前是否应重置任何标志?

Joh*_*itb 18

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

你应该设置fail位.如果流的用户想要抛出异常,他可以配置流(使用istream::exceptions),并且流将相应地抛出.那么我会这样做的

stream.setstate(ios_base::failbit);
Run Code Online (Sandbox Code Playgroud)
  1. 如果流中存在格式错误的数据,流应处于什么状态?

对于不符合您要读取的格式的格式错误的数据,通常应该设置该fail位.对于内部流特定错误,使用该bad位(例如,如果没有连接到流的缓冲区).

  1. 在返回操作符链接的引用之前是否应重置任何标志?

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


要检查流是否处于良好状态,可以使用istream::sentry该类.创建一个对象,传递流和true(告诉它不要立即跳过空格).哨兵将计算为false如果eof,failbad位.

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

  • 对于格式错误的输入,不消耗流中的任何字符都是不可能的.你需要任意回溯.常见的行为是使用有效前缀. (2认同)