这个标准是否保证了上述代码是可移植的,即适用于所有符合标准的
std::ostream
实现?
是的。
在调用
std::ostream(&dsb)
的时候,
DerivedOutputStream
的
dsb
成员已经被分配但未初始化。也就是说,我们可以获取它的地址,但我们不能读取其(未初始化的)值。
如问题中所链接的那样,
[ostream.cons] 指定了
std::basic_ostream
的构造函数,特别地,你的示例中选择的是
[ostream.cons]/1。
```
explicit basic_ostream(basic_streambuf* sb);
作用:
使用basic_ios::init(sb) ([basic.ios.cons])初始化基类子对象。
后置条件:
rdbuf() == sb。
```
`
[tab:basic.ios.cons]`描述了调用`void init(basic_streambuf* sb)`的作用,其中一个特别是上面构造函数中描述的后置条件。
rdbuf() == sb
其中其余部分不对指向的底层缓冲区执行读取访问操作。
现在,
rdbuf()
只是一个指针,因此这意味着通过值传递给 init 的
sb
指针(即指针本身)将用于初始化
rdbuf()
。但是,在此时没有读取
sb
指向的底层缓冲区的副作用。
[...] 不允许其他效果,...?
实际上,特别是对于
void init(basic_streambuf<charT, traits>*)
函数的实现需要尊重并不扩展
[tab:basic.ios.cons] 中明确定义的效果。
这篇(相当老的)文章...
请注意,[ostream.cons]的状态自C++诞生以来基本上没有改变;例如,我们可以查看{{link2:1994年9月C ++工作文件}}中的{{link1:[lib.input.output]}}。
27.2.4.1.1 basic_ostream constructor [lib.basic.ostream.sb.cons]
basic_ostream(basic_streambuf<charT,baggage>* sb);
1 Constructs an object of class basic_ostream, assigning initial values to the base class by calling basic_ios<charT,baggage>::init(sb)
.
并且
27.1.3.1.34 basic_ios::init [lib.basic.ios::init]
void init(basic_streambuf<charT,baggage>* sb_arg);
1 The postconditions of this function are indicated in Table 8:
Table 8--init effects
+----------------------------------+
|Element Value |
+----------------------------------+
|sb sb_arg |
|tiestr a null pointer |
|state goodbit if sb_arg is |
| not a null pointer, |
| otherwise badbit. |
|except goodbit |
|fmtfl skipws | dec |
|wide zero |
|prec 6 |
|fillch the space character |
|loc new locale(), which |
| means the default value |
| is the current global |
| locale;9) |
|iarray a null pointer |
|parray a null pointer |
+----------------------------------+
这段文字描述了通过
init()
调用进行相同委派并具有明确定义效果的过程。
ifstream(const char* s, ...);
并没有明确指定s
必须是指向有效c字符串的指针 (http://eel.is/c++draft/ifstream#cons-2),但是传递一个指向某些(未初始化)内存的指针是一种未定义行为。 - eadbasic_ostream
的实现中,构造函数也会将存储gcount
结果的成员变量初始化为0,但这是一个实现细节,在标准的“效果”下未提及。因此,我不确定是否可以遵循标准给出任何保证。 - ead