为什么C++中的流?

oh *_*boy 8 c++ stream

众所周知,有些库使用的流如iostreamfstream.

我的问题是:

  • 为什么流?为什么他们不坚持类似的功能print,fgets等等(例如)?

它们需要自己的操作符<<,>>但它们所做的一切都可以用上面的简单函数实现,也可以用函数实现

printf("Hello World!");
Run Code Online (Sandbox Code Playgroud)

对我来说比我更具可读性和逻辑性

cout << "Hello World";
Run Code Online (Sandbox Code Playgroud)

我还认为C++中的所有字符串抽象都编译为二进制的(效率较低的)标准函数调用.

sho*_*osh 24

流具有更好的类型安全性.

例如,printf("%s", a);如果a是整数,可能会出现可怕的错误.cout << a;没有这个问题.

另一个问题是流更好地符合面向对象的设计方法.

例如,你有一个简单的应用程序写入一些输出,然后你希望输出转到文件而不是控制台.使用C呼叫,您必须将所有呼叫替换printf为呼叫,fprintf并注意保持FILE*一直.使用流只需更改您正在使用的流的具体类,就是这样,大多数代码保持相同:

void doSomething(ostream& output)
{
   output << "this and that" << a;
}

doSomething(cout);
doSomething(ofstream("c:\file.txt"));
Run Code Online (Sandbox Code Playgroud)


Tyl*_*nry 9

首先,它允许您利用C++对象模型来创建不关心它们是写入标准输出,文件还是网络套接字的函数(如果您有一个源自的网络​​套接字ostream).例如

void outputFoo(std::ostream& os)
{
  os << "Foo!";
}

int main()
{
  outputFoo(std::cout);

  std::ofstream outputFile("foo.txt");
  outputFoo(outputFile);

  MyNetworkStream outputSocket;
  outputFoo(outputSocket);
}
Run Code Online (Sandbox Code Playgroud)

同样对于输入流.

在输入和输出对象时,Streams也有优势.如果你想用一个对象读取会发生什么scanf

MyObject obj;
scanf("??", &obj); // What specifier to use? 
Run Code Online (Sandbox Code Playgroud)

即使有适当的说明符,如何scanf知道如何填写对象的成员?使用C++流,您可以重载operator<<和写入

MyObject obj;
std::cin >> obj;
Run Code Online (Sandbox Code Playgroud)

它会奏效.同样std::cout << obj如此,您可以在一个地方编写对象序列化代码,而不必担心其他任何地方.

  • @shoosh`bool :: asio :: ip :: tcp :: iostream`? (5认同)

小智 7

C++流是类型安全的.在C中,如果你说:

double d = 1.23;
printf( "%d", d );
Run Code Online (Sandbox Code Playgroud)

即使转换不正确,也不能保证收到错误消息.

你似乎在问非常基本的C++问题.你使用哪种C++教科书不包括它们?


Edw*_*nge 5

printf对于一个人来说不是类型安全的.cout界面也更通用,这允许printf版本无法使用很多东西.一个很好的例子是你的类型的流操作符,如果你正确的话,将std :: ostream称为流,而不是cout.因此,您只需使用不同的流即可更改输出的目标.要使用printf执行此操作,您必须执行大量依赖于平台的输出句柄覆盖.

我还认为C++中的所有字符串抽象都编译为二进制的(效率较低的)标准函数调用.

想想你想要的一切.在你真正测试你的假设之前,你的意见不会太重.此外,您需要考虑抽象的丢失,这在现代软件开发中通常更为重要.