gpt4 book ai didi

c++ - cstdio 流与 iostream 流?

转载 作者:IT老高 更新时间:2023-10-28 12:43:17 29 4
gpt4 key购买 nike

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

现在,我一直认为 C 中的 stdoutstderrstdin 本质上是封装在 iostreams 中的 C++ 中的一组对象中类。但如果它们必须相互同步,这将表明 C++ 的 iostream不是 C 的 stdin< 的包装器

我对此感到很困惑?有人可以澄清 C++ 的 iostream 和 C 的 stdio 是如何不同 做同样事情的事情,只是在不同的抽象级别?我以为他们是同一件事!?

它们是如何同步的?我一直认为它们是同一个东西,本质上是一个包裹另一个。

最佳答案

C 和 C++ 标准对事物的实现方式没有任何要求,只是对某些操作的效果做出了要求。对于<stdio><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 ,分别是:当用户从 stdin 中读取两者时会发生什么?和 std::cin ?如果这些流中的任何一个从底层 OS 流中读取字符缓冲区,则读取将出现乱序。同样,如果两个 stdoutstd::cout当用户同时写入两个流时,使用的独立缓冲区字符将以意外的顺序出现。因此,标准 C++ 流对象(即 std::cinstd::coutstd::cerrstd::clog 及其对应的宽字符)有一些特殊规则,要求它们与各自的 <stdio> 同步。对方。实际上,这意味着这些 C++ 对象要么直接使用通用实现,要么根据 <stdio> 实现。 不缓冲任何字符。

我们意识到,如果实现不共享一个共同的基础,这种同步的成本是相当可观的,并且对于某些用户来说可能是不必要的:如果用户只使用 <iostream>他不想支付额外的间接费用,更重要的是,他不想支付不使用缓冲区所带来的额外成本。对于谨慎的实现,不使用缓冲区的成本可能相当高,因为这意味着某些操作最终不得不在每次迭代中进行检查,并且可能需要进行虚函数调用,而不是偶尔进行一次。因此,std::sync_with_stdio()可用于关闭此同步,这可能意味着标准流对象或多或少完全改变了它们的内部实现。由于标准流对象的流缓冲区可以被用户替换,不幸的是,流缓冲区不能被替换,但流缓冲区的内部实现是可以改变的。

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

关于c++ - cstdio 流与 iostream 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9653751/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com