【问题标题】:Exactly how do << and >>, as used in streams, work? [duplicate]流中使用的 << 和 >> 究竟是如何工作的? [复制]
【发布时间】:2016-02-25 19:31:27
【问题描述】:

我一直认为 cout 和 cin 调用是这样的:

cout << someVar

告诉编译器我们将 someVar 的值转储到 cout 中,就像我们可以将水转储到物理流中一样。同样,

cin >> someVar

告诉编译器用来自 cin 的数据(空格之前的所有内容)填充 someVar,就像我们可以用物理流中的水填充桶一样。

但是 > 是按位运算符。 > 将位向右移动。为什么cout &lt;&lt; Hello Worldcout &lt;&lt; My name is John 不让控制台不说“Hello World”?

编辑: 这不是“运算符重载”的重复,因为虽然该问题可能隐含地涉及 > 运算符,但我目前提出的问题并未涉及重载。

【问题讨论】:

  • C++ 允许重载运算符。
  • 因为 c++ 允许运算符重载。基本上,您可以随意更改操作员的意思/行为。
  • 投票重新开放的理由是,虽然链接的问题有一个与按位运算符相关的答案,但问题本身涉及运算符重载的规则和习语。
  • 虽然链接的问题可能隐含地解决了 > 运算符,但我目前提出的问题并未解决重载问题。
  • 伙计们,我不满意这个问题是重复的。链接的副本似乎处理运算符重载的规则和习语 - 换句话说,如何重载运算符。我的问题是为什么 C++ 让你使用位移运算符将输出插入到流中并从流中提取输出。

标签: c++


【解决方案1】:

在 C++ 中,您可以重载运算符。这里&gt;&gt;&lt;&lt; 是这样的重载运算符,在这种情况下是std::basic_ostream (std::basic_istream) 的成员,形式为

std::basic_ostream& operator<<(int); // overload for int

所以当你写的时候

std::cout << 42;

调用被翻译成

std::cout.operator<<(42);

请注意,operator&lt;&lt;operator&gt;&gt; 也可以定义为非成员函数,在这种情况下,它们的形式类似于:

std::basic_ostream& operator<<(std::basic_ostream& os, const Foo& foo)

Foo 是一些自定义类型。这就是您实现一般流提取和插入的方式,重载非成员operator&lt;&lt;operator&gt;&gt;,因为您无权访问std::basic_ostreamstd::basic_istream 的内部。

参见例如this 了解更多详情。

【讨论】:

    【解决方案2】:

    请记住,在 C++ 中,它们并不是字面上的位移运算符,它们只是运算符。您可以将它们定义为您想要的任何含义,并在流的上下文中执行输入和输出操作。

    不要太拘泥于“告诉编译器”的东西。这并不意味着什么。而是在代码中考虑“被定义为意味着”。标准库没有什么神奇之处,它只是你可以自己编写的 C++ 代码。编译器只负责将其分解为机器代码。

    例如,您可以在已定义的类上编写自己的&lt;&lt; 运算符,将事物添加到数组中,或者为输出流创建一个特殊版本,以特定方式处理事物。这完全取决于您。

    【讨论】:

    • 因此,当用于流时,它们不是按位运算符。
    • 它们被重新定义为完全不同的意思。 C++ 有许多预定义的运算符,所有这些都可以重新定义为几乎任何意思。除了 intchar 这样的基本类型之外,您需要查看它们的功能。例如,+ on strings 将它们组合在一起。如果您曾经看到一个名为 operator 的方法,那就是它正在做的事情。
    【解决方案3】:

    &lt;&lt; 是一个运算符。而在 C++ 中,您可以overload operators 对不同的类型执行不同的操作。

    编译器能够确定正在操作的类型并以不同的方式执行代码。因此,对于流,它会将数据发送到需要去的地方并得到适当的处理。

    【讨论】:

      【解决方案4】:

      对于>的默认用法:

      C++ : Whats does this sign “<<” do?

      > 也可以重载:

      http://en.cppreference.com/w/cpp/language/operators

      编辑此问题可能与此问题重复:

      How does the << Operator exactly work?

      【讨论】:

        【解决方案5】:

        所以&lt;&lt;&gt;&gt; 是正确的context 中的位运算符,但它们在不同的上下文中成为流运算符。就像您可以重载一个函数以接受不同的参数并在给定这些不同参数的情况下表现不同一样,这些运算符可以(并且已经)在特定上下文中被覆盖。

        流插入意味着将一些东西放入一个字符串中(如cout &lt;&lt; "Hello";),在这种情况下,左操作数是一个流,而右操作数是一个字符串,当我们告诉它“转储”到时知道要做什么如你所说,流。

        流提取 (&gt;&gt;) 是另一种上下文,其中通常按位运算符具有完全不同的含义。如果左操作数支持这种提取(流),并且提取的值与右操作数的类型匹配,那么我们执行的是流操作而不是位移。

        【讨论】:

          【解决方案6】:

          &lt;&lt;&gt;&gt; 是 C++ 中的运算符。在原始类型上,它们会按位移位,但它们可以作为成员函数重载或采用任意两个参数。本质上,这只是调用重载的T operator&lt;&lt; (...) 函数的一种更简单的方法。

          以下是为std::istreamstd::ostream 提供的库重载。

          http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/

          您可以重载以将用户定义的类型作为参数。

          http://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

          【讨论】:

            猜你喜欢
            • 2012-10-07
            • 2012-01-26
            • 2019-10-12
            • 1970-01-01
            • 2023-03-16
            • 1970-01-01
            • 2017-05-13
            • 2020-10-17
            • 1970-01-01
            相关资源
            最近更新 更多