cstdio流与iostream流?

Ton*_*ion 30 c c++ iostream stream cstdio

我刚刚了解到ios_base::sync_with_stdio函数的存在,它基本上允许你关闭(或者如果你已经关闭它)iostream在C++中使用的cstdio流和作为标准C的一部分的流之间的同步.

现在,我一直认为stdout,stderrstdin用C基本上包裹在一组++的输入输出流类在C对象的.但如果它们必须彼此同步,这将表明C++的iostream不是 C stdin等的包装器 .

我很困惑这个?有人可以澄清C++的的iostream和C的标准输入输出是如何不同的东西,做同样的事情,只是在不同的抽象级别?我以为他们是一回事!

它们是如何同步的呢?我一直认为它们是同一个东西,一个包装另一个,基本上.

Die*_*ühl 35

C和C++标准对事物的实现方式没有要求,只是对某些操作的影响.对于<stdio>vs <iostream>功能,这意味着可以包装另一个,两者可以基本相同,或者它们完全独立.从技术上讲,使用通用实现是理想的有几个原因(例如,不需要显式同步,并且将有一个定义的机制来扩展FILE*用户定义的系统),但我不知道任何系统实际上这样做.将一个实现作为另一个实现的包装是可能的,并且实现<iostream>s <stdio>是典型的实现选择,尽管它具有为某些操作引入额外成本的缺点,并且大多数C++标准库已经转向使用完全独立的实现.

不幸的是,包装和独立实现都有一个共同的问题:当完成一个字符级别时,I/O非常低效.因此,基本上必须缓冲字符并读取或写入缓冲区.这适用于彼此独立的流.美中不足的是标准C流stdin,stdout,stderr和他们的C++窄字符同行std::cin,std::cout,std::cerr/ std::clog和C++宽字符同行std::wcin,std::wcout,std::wcerr/ std::wclog,分别为:当用户无论是从读会发生什么stdinstd::cin?如果这些流中的任何一个从底层OS流中读取字符缓冲区,则读取将无序显示.类似地,如果两个stdout并且std::cout使用了独立缓冲区,则当用户同时向两个流写入时,字符将以意外顺序出现.其结果是,有对标准C++流对象特殊规则(即std::cin,std::cout,std::cerr,和std::clog以及它们的宽字符对应物),其使得它们与它们各自的同步任务<stdio>对应物.有效地,这意味着,具体地,这些C++对象直接或它们在以下方面实现的使用常见的实现<stdio> 不缓冲的任何字符.

已经意识到,如果实现不共享公共基础并且对于某些用户可能是不必要的,则该同步的成本是相当大的:如果用户仅使用<iostream>他不想为额外的间接付费,并且更重要的是,他不想支付因不使用缓冲带而产生的额外费用.对于仔细的实现,不使用缓冲区的成本可能非常大,因为这意味着某些操作最终必须在每次迭代中进行检查并可能进行虚拟函数调用,而不是偶尔进行一次.因此,std::sync_with_stdio()可用于关闭此同步,这可能意味着标准流对象或多或少完全改变其内部实现.由于标准流对象的流缓冲区可以由用户替换,遗憾的是,流缓冲区不能被替换,但是可以改变流缓冲区的内部实现.

<iostream>库的良好实现中,所有这些仅影响标准流对象.也就是说,文件流应该完全不受此影响.但是,如果您想使用标准流对象并希望获得良好的性能,您显然不希望混合<stdio>,<iostream>并且您希望关闭同步.特别是,在比较I/O性能时<stdio>,<iostream>你应该意识到这一点.