【问题标题】:Why does a insertion/extraction operator's overloaded function need ostream/istream argument?为什么插入/提取运算符的重载函数需要 ostream/istream 参数?
【发布时间】:2017-10-13 05:27:51
【问题描述】:

考虑以下带有重载插入和提取运算符的代码。

#include <iostream>

using namespace std;

class CTest
{
    string d_name;
public:
    friend ostream & operator<<(ostream & out, CTest & test);
    friend istream & operator>>(istream & in, CTest & test);
};

ostream & operator<<(ostream & out, CTest & test)
{
    out << "Name: " << test.d_name;
    return out;
}

istream & operator>>(istream & in, CTest & test)
{
    cout << "Enter your name: ";
    string name;
    if(in >> name)
        test.d_name = name;

    return in;
}

int main()
{
    CTest test;
    cin >> test;   // (1)
    cout << test;  // (2)
}

接下来的问题,参数 ostream & out 和 istream & in 的意义是什么? 由于我们只能看到一个参数(cin >> test 或 cout

【问题讨论】:

  • cin &gt;&gt; test 中有两个参数。
  • istream 不是cin 的同义词,而是它的类型。
  • 如果你不将流传递给operator,函数应该如何知道它应该将数据写入哪个流或从哪个流读取它? 流式操作符 设计用于处理任何流(标准输入和输出、文件流、网络流、用户定义的流……)。所以问题应该是这些运算符函数如何获得两个参数。
  • 您的 插入操作符 (&lt;&lt;) 应该使用 const ref: CTest const&amp; test
  • 我的疑问是 - 对于函数,参数在括号中传递,例如 - fn(p1, p2);但是在这里我无法理解这个函数的设计,其中参数是非常规地传递的。 cout(参数 1)

标签: c++ oop operator-overloading


【解决方案1】:

因为在cin &gt;&gt; testcout &lt;&lt; test 中都存在两个参数。

cin 的类型为 istream

cout 的类型为 ostream

这些类型可能不是coutcin。例如,它们可以是 cerrclogstringstream

这就是为什么您需要两个参数,因为一个是流的变量,另一个是要流式传输的对象。

【讨论】:

  • 其他istreams 和ostreams 可以包括文件流、cerrclog(尽管很少使用那个)和stringstreams。这就是我在标准库中能想到的全部内容,但我可能会遗漏一些,其他库(如 Boost)实现了自己的。
  • @gsamaras 我无法理解这个以这种非常规方式接受参数的函数的设计。请给它一些启发好吗?
  • @Rahul 例如,您拥有的&lt;&lt; 运算符可以将test.d_name 写入coutcerr。您希望拥有这种灵活性,因为现在您可以编写(cout &lt;&lt; testcerr &lt;&lt; test)。希望对您有所帮助。
  • 感谢您的回复。是的,我知道使用 istream/ostream 是为了方便使用 cerr 等。我的疑问是 - 对于函数,参数在括号中传递,例如 - fn(p1, p2);但是在这里我无法理解这个参数非常规传递的函数的设计。 cout(参数 1)
【解决方案2】:

为了更好地理解这两个参数的来源,你可以重写你的 main() 函数如下:

int main()
{
    CTest test;
    operator>>(std::cin, test);
    operator<<(std::cout, test);
}

【讨论】:

    【解决方案3】:
    cin >> test;
    

    这里,左操作数是std::istream 类型的cin 对象,右操作数是您的CTest 类对象。

    &gt;&gt;操作符原型

    friend istream& operator >> (istream& s, Your class &);
    

    所以,我们在内部传递了两个参数。

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 2020-02-10
      • 2015-05-08
      • 2016-07-28
      • 2011-08-31
      • 2014-05-29
      • 1970-01-01
      • 2011-03-19
      相关资源
      最近更新 更多