2010-02-19 55 views
23

在线参考文献对std::iostream::sentry的目的有比较简短和模糊的描述。我应该什么时候关心自己这个小小的生物?如果只是为了内部使用,为什么要公开它?什么时候应该关注std :: iostream :: sentry?

+0

既然标识符是一个小动物?它肯定不会少! :D – Hogan 2010-02-19 18:21:07

回答

12

大多数人永远不会写任何需要处理创建哨兵对象的代码。当/从数据流中提取数据(或将其插入)流对象本身的流缓冲区时,需要使用一个哨兵对象。

只要你插入/拔出操作员使用其它的iostream成员/运营商做的工作,它必须处理创建一个哨兵对象(因为这些其他的iostream运营商将创建和销毁岗哨对象需要 )。

+0

啊,谢谢。这对我来说最有意义(尤其是底层的流缓冲区)。我对为什么显示如何编写自己的自定义流操作符的教科书示例从未提到过哨兵对象感到困惑。 – 2010-02-19 20:35:15

12

无论何时需要使用流提取或输出数据,都会使用它。也就是说,无论何时制作operator>>抽取运算符或插入运算符operator<<

它的目的是为了简化逻辑:“是否设置了任何失败位?同步缓冲区。对于输入流,可选择地将任何空白留空,好吗,准备好了吗?

所有提取流运营商应该首先:

// second parameter to true to not skip whitespace, for input that uses it 
const std::istream::sentry ok(stream, icareaboutwhitespace); 

if (ok) 
{ 
    // ... 
} 

而且所有插入流运营商应该首先:

const std::ostream::sentry ok(stream); 

if (ok) 
{ 
    // ... 
} 

这只是一个做的(类似的东西)的清洁方法:

if (stream.good()) 
{ 
    if (stream.tie()) 
     stream.tie()->sync(); 

    // the second parameter 
    if (!noskipwhitespace && stream.flags() & ios_base::skipws) 
    { 
     stream >> std::ws;    
    } 
} 

if (stream.good()) 
{ 
    // ... 
} 

ostream只是跳过空白部分。

+2

如果我使用其他流成员函数来实现一个自定义的'operator >>',是否仍然需要(或者是一个好主意)来使用哨兵? – 2010-02-19 18:35:02

+0

插入操作符怎么样? ostream还定义了哨兵。 – 2010-02-19 18:36:49

+0

@GMan:我听说你。似乎可以在iostreams上编写整本教科书。 :-) – 2010-02-19 18:54:13

1

对于除基本类型(int,double等)以外的任何其他格式化的输入没有太大意义,并且只有从非交互式流(例如istringstream)中获取时才可以使用。所以你可能不应该首先执行op >>,因此不必担心哨兵对象。

+0

如果我想要重载操作符>>能够方便地对基本类型的元组进行格式化输入,该怎么办?例如:'struct Point {double x,double y};要点; file >> point;'重载的操作符>>用操作符>>来实现,用于基本类型。 – 2010-02-19 20:29:18

+0

@Emile假设点被格式化为“x,y”,那么令人惊讶地难以实现op >>,因此它适用于点AND与所有其他格式化输入操作符一起使用时正确工作。基本上,你最好是编写函数来解析你所期望的具体输入,而不是一天结束时不能处理真实世界输入的一般性计划。 – 2010-02-19 20:34:46

+0

@尼尔:我明白你在说什么。但是,自定义操作符>>的合法用法可能是从对称操作符<<生成的文件中读回数据。这似乎是Boost.Serialization库背后的前提。 – 2010-02-19 20:43:02

相关问题