请考虑以下内容:
std::ostream out(nullptr);
这合法且明确定义吗?
如果我现在这样做呢:
out << "hello world\n";
这是否合法且定义得清楚?如果是,则可能是某种无操作。
请考虑以下内容:
std::ostream out(nullptr);
这合法且明确定义吗?
如果我现在这样做呢:
out << "hello world\n";
这是否合法且定义得清楚?如果是,则可能是某种无操作。
是的,实例化该流是合法且被充分定义的。您可以安全地将其与另一个流交换,或在以后的某个时间给它一个新指针(这次是指向现有缓冲区)。输出操作本身确实是不执行操作的。
原因如下:
构造函数没有非空的前置条件,只有这个后置条件:
[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_ios<charT,traits>::init(sb)
(27.5.5.2)对基类赋予初始值,构造basic_ostream
类的对象。
init(sb)
调用的效果是在sb
为NULL时设置流的badbit
:
[C++11: 27.5.5.2/3]:
后置条件:此函数的后置条件在表128中指示。
[C++11: 表128]:
[..]rdstate()
:如果sb
不是空指针,则为goodbit
;否则为badbit
。[..]
输出操作 将 导致与解除引用空指针等价的操作:
[C++11: 27.7.3.1/2]:
有两组成员函数签名共享相同属性:格式化输出函数(或插入器)和非格式化输出函数。 这两组输出函数通过等效于调用rdbuf() -> sputc(int_type)
的操作来生成(或插入)输出字符。 它们可以使用其他 public 成员变量除了不能调用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
类对象来完成。如果此对象转换为bool
类型的值时返回true
,则该函数将努力生成请求的输出。 [..]
…这意味着当已经设置 badbit
时,根本不会进行任何输出操作。
std::ostream
来有效地创建 /dev/null
。 - πάντα ῥεῖ