"<<"和">>"运算符如何进行I/O操作?

Guy*_*ean 11 c++

可能重复:
运算符重载

我正在期待已久的回归C++,并且有一些基本符号在其他语言中看起来并不那么突出.

如果你看一下这行代码

cout << "firstvalue is " << firstvalue << endl;
Run Code Online (Sandbox Code Playgroud)

我意识到这是做什么的.它将"firstvalue is x"写入控制台.x是firstvalue的值.但是,我对"<<"或">>"双角括号一无所知.我无法研究它们或它们做什么,因为我不知道它们的正式名称.

我的问题是,上述陈述中实际发生了什么(一步一步)?这些"<<"是什么?我想我明白cout是用于写入控制台的标准库函数.但是我习惯于使用objective-c或点符号.我没有看到这个"cout"函数是什么对象.

我可以更容易地理解printf,因为至少它为参数提供了大括号.例如printf("你的字符串在这里").

pmr*_*pmr 17

C++允许运算符重载.这意味着用户定义的类型可以在内置运算符上定义自己的行为.在这种情况下,运算符称为:left shiftright shift运算符.这些运算符传统上一直用于位移,但标准库将它们重新用于表示流操作.

您可以在此处找到C和C++中可用运算符的列表.

在您的情况下,您将字符串文字和某种类型的值流式传输到std :: cout,这是std :: basic_ostream类型的对象.

一步步

在应用优先规则后,您的代码如下所示:

((cout << "foobar") << x) << endl;
Run Code Online (Sandbox Code Playgroud)

编译器基本上将object << object表达式转换为函数调用.

operator<<(operator<<(operator<<(cout, "foobar"), x), endl);
Run Code Online (Sandbox Code Playgroud)

然后它将确定要调用的过载.(这真的很棘手.现在它应该足以让人相信它只是寻找operator<<带有匹配参数的重载).

basic_ostream的大多数内置重载都在这里这里.


650*_*502 5

<<操作者是在C ++中的“算术左移”。例如:

3 << 2
Run Code Online (Sandbox Code Playgroud)

计算结果为12。原因是3的二进制表示为

00000011
Run Code Online (Sandbox Code Playgroud)

将它向左移动两次

00001100
Run Code Online (Sandbox Code Playgroud)

结果的数值为12。

用输出做什么呢?没事,实际上。但是,在C ++中,由于重载,您可以重新定义运算符的含义。C ++标准库决定将左移运算符的含义重新定义为“发送到流”。

所以发生的是

std::cout << "whatever"
Run Code Online (Sandbox Code Playgroud)

返回值为value std::cout,但副作用是它输出字符串“ whatever”。

选择该运算符是因为它具有合理的优先级(重载不能更改优先级,并且您不能定义新的运算符),并且其形状使其看起来有些“自然”。但是请注意,左移运算符只是普通运算符,例如,不能保证求值顺序:

std::cout << f() << g() << h();
Run Code Online (Sandbox Code Playgroud)

这里的输出将是calling的结果f(),然后是calling的结果,再接着是calling g()的结果h()……但是这些函数本身可以以不同的顺序h()被调用,例如可以首先被调用!

因此,从某种意义上说,运算符的“顺序外观”具有误导性,因为它与输出顺序有关,而与评估顺序无关。