use*_*710 14 c++ iostream ostream
为什么我不能像这样为我的输出创建一个"空"流
std::ostream out;
Run Code Online (Sandbox Code Playgroud)
?
此行是与两个明显违法clang 3.4,并gcc 4.8.1根据与Linux的libstdc++,我真的不知道为什么,我的意思是,为什么我不能只是出于创建流无处并使用它就像我想?请注意std::ofstream out;100%确定.我只是没有得到这背后的逻辑.如果你认为在创建之后我可以使用这个缓冲区并与其他缓冲区共享一个公共缓冲区,这就更奇怪了,copyfmt所以我没有真正需要std::ostream将对象初始化为对象的创建是有用的.
请不要偏离这一点,我不需要stringstreams,ios因为我必须做的事情以及他们提供的方法和属性,我需要流.
Jam*_*nze 13
我承认我也不理解.我根本找不到任何默认构造函数,std::istream如果你想创建一个双向流,我认为你会想要一个,因为奇怪的方式std::ios_base有效:构造函数不初始化任何东西,但派生类必须std::ios_base::init显式调用在它的构造函数中.当多重继承参与(即双向IO,所在班级从两个派生
std::istream和std::ostream),我希望只有最派生类中调用std::ios_base::init.(在
std::iostream,std::ios_base::init将被调用两次.)事实上,在查找标准之前,我正要回答默认构造函数是受保护的,因为它没有调用std::ios_base::init,而是直接使用它,而不是在派生类中,会导致未初始化的流.
无论如何,你的直接问题有一个简单的解决方案:
std::ostream out( NULL );
Run Code Online (Sandbox Code Playgroud)
另外:稍后设置其接收器所需的功能是非const版本rdbuf(),而不是copyfmt(). rdbuf()用于读取和指针设置为streambuf,
copyfmt()复制格式化标志,但并没有指针触碰到streambuf.
所以你可以这样做:
std::ostream out( NULL );
// ...
std::filebuf fileBuffer;
if ( filenameGiven ) {
fileBuffer.open( filename.c_str(), std::ios_base::out );
}
if ( fileIsOpen() ) {
out.rdbuf( &fileBuffer );
} else {
out.rdbuf( std::cout.rdbuf() );
}
Run Code Online (Sandbox Code Playgroud)
(我这么做了.事实上,我认为这是通常的习惯,因为你不知道是否要输出到文件或者std::cout.)
编辑:
而另一个更正:非const版本的rdbuf调用clear(),所以你不必.(我知道我没有打电话就这样做了clear(),但是当我看到init那套badbit......)
无论如何:摘要是:通常更喜欢将指向有效streambuf的指针传递给构造函数std::ostream,但是如果你不能,那么传递空指针并在以后使用设置有效指针是完全有效的
rdbuf().而另外说的答案是完全错误的.
std::ostream 在概念上是抽象的 - 你不应该创造它们(但是有关它的更多细节,请参见其他答案).
std::stringstream给你一切std::ostream,因为它源于它.这也意味着std::ostream&您可以在任何地方(例如在函数参数中)传递std::stringstream对象.
你说"没有必要初始化[...]有用".这毫无意义.你不能使用任何尚未初始化的东西:甚至是ints.
在默认的构造函数std::basic_ostream是protected因为它通常没有任何意义,创建一个std::basic_ostream没有设置它std::basic_streambuf,默认的构造函数实际上没有做任何初始化(见下文).但是,有另一个构造函数将流缓冲区作为参数.如果你真的需要一个std::ostream没有设置做任何事情的东西,你可以使用那个构造函数:
std::ostream out(0);
Run Code Online (Sandbox Code Playgroud)
这std::ostream将具有该std::ios_base::badbit设置,直到使用设置流缓冲区std::ios::rdbuf().
std::ostream默认构造函数存在的根本原因protected是它实际上故意不做任何有用的事情!特别是,调用此构造函数[来自另一个派生类]将根本不初始化流缓冲区:标准不明确强制任何行为,即默认构造函数隐式地具有生成默认构造函数的行为(或者, C++ 2011好像是使用它定义的= default).要初始化流缓冲区,需要调用std::ios::init().这种奇怪行为的原因是构造进一步派生类std::iostream的std::ios对象将初始化对象两次,一次通过std::ostream和一次通过std::istream.
与其他一些答案不同,std::ostream它根本不是抽象的.实际上,它只有一个virtual函数,它就是它的析构函数(析构函数virtual恰好是我的错;我并不完全相信强制它是一个好主意).