请考虑以下事项:
std::ostream out(nullptr);
这是否合法且定义明确?
如果我现在这样做:
out << "hello world\n";
这是合法且明确的吗?如果是这样的话,大概是一种无操作的行为?
答案 0 :(得分:24)
是的,实例化该流是合法且定义良好的。您可以安全地将其与另一个流交换,或者稍后给它一个新的指针(这次是对现有的缓冲区)。输出操作本身确实是无操作。
这就是原因:
构造没有非null前置条件,并且只有这个后置条件:
[C++11: 27.7.3.2/2]:
后置条件:rdbuf() == sb
。
有趣的是,它明确指出在构造函数中sb
不应该执行任何操作:
[C++11: 27.7.3.2/4]:
备注:不对rdbuf()
执行任何操作。
但请注意:
[C++11: 27.7.3.2/1]:
效果:构造类basic_ostream
的对象,通过调用basic_ios<charT,traits>::init(sb)
(27.5.5.2)将初始值分配给基类。
当init(sb)
为NULL时,badbit
调用会对流设置sb
:
[C++11: 27.5.5.2/3]:
后置条件:此函数的后置条件如表128所示。
[C++11: Table 128]:
[..]rdstate()
:goodbit
如果sb
不是空指针,否则badbit
。 [..]
输出操作将导致相当于取消引用空指针的操作:
[C++11: 27.7.3.1/2]:
两组成员函数签名共享公共属性:格式化的输出函数(或插入器)和未格式化的输出函数。 两组输出函数都通过等同于调用rdbuf()->sputc(int_type)
的操作生成(或插入)输出字符。他们可能使用basic_ostream
的其他公共成员,除非他们不会调用任何虚拟成员除rdbuf()
,overflow()
和xsputn()
之外的sync()
成员。
除了它永远不会这么远,因为basic_ostream::sentry
构造:
[C++11: 27.7.3.4/3]:
如果在完成任何准备工作后,os.good()
为true
,ok_ == true
则为ok_ == false
。
和explicit operator basic_ostream::sentry::bool() const;
:
[C++11: 27.7.3.4/5]:
效果:返回ok_
。
和
[C++11: 27.7.3.7/1]:
每个未格式化的输出函数通过构造类sentry
的对象开始执行。如果此对象返回true
,则在转换为类型bool
的值时,该函数会尝试生成请求的输出。 [..]
......这意味着当badbit
已经设置时,根本不会发生任何输出操作。