【问题标题】:Problems with istream& operator >>istream& 运算符的问题 >>
【发布时间】:2015-07-25 02:54:35
【问题描述】:

我仍然想知道 istream 运算符>>。 在我的函数istream& operator >> (istream &is, Student& a) 中,我没有使用is,但仍然在函数末尾返回它。我仍然得到cin >> a 的正确答案。谁能解释一下为什么?

#include <iostream>

using namespace std;

class Student
{
private:
    int age;
public:
    Student() : age(0){}
    Student (int age1) : age(age1) {}
    void setAge();
    int getAge(){return age;}
    friend istream& operator >> (istream& is, Student& a);
};

istream& operator >> (istream &is, Student& a)
{
    a.setAge();
    return is;
}
void Student::setAge(){
    int age1;
    cout << "input age of the student: "<< endl;
    cin >> age1;
    age = age1;
}

int main()
{
    Student a;
    cin >> a;
    cout << "Age of Student is " << a.getAge() << "?";
}

【问题讨论】:

  • 问问自己is参数对你的操作员有什么意义,如果你只是要在setAge中点击cinsetAge 应该这样做:采用 int 参数并设置 age 成员。留下你如何获得传递的价值。

标签: c++ operators cin istream


【解决方案1】:

这很好,因为你正在调用

cin >> a;

如果你这样做了

ifstream ifs ("test.txt", ifstream::in);
ifs >> a;

然后您的程序将从标准输入读取,而不是像它应该做的那样从文件 (test.txt) 读取。

正确的实现应该是

istream& operator >> (istream &is, Student& a)
{
    return is >> a.age;
}

现在如果你打电话

cin >> a;

它将从标准输入中读取

如果你打电话

ifs >> a;

它会从文件中读取。

【讨论】:

    【解决方案2】:

    在我的函数istream&amp; operator &gt;&gt; (istream &amp;is, Student&amp; a) 中,我没有使用is,但仍然在函数末尾返回它。我仍然得到cin &gt;&gt; a 的正确答案。谁能解释一下为什么?

    因为Student::setAge() 直接访问cin,这与您的示例中is 恰好指向的流相同。

    这不是正确的设计。成员设置者不应提示用户输入。您应该首先提示输入,然后将值传递给您的设置器。该类应该不知道其值的来源。

    改用类似的东西:

    #include <iostream>
    
    using namespace std;
    
    class Student
    {
    private:
        int age;
    public:
        Student() : age(0){}
        Student (int age1) : age(age1) {}
        void setAge(int value);
        int getAge(){return age;}
        void readFrom(istream& is);
    };
    
    istream& operator >> (istream &is, Student& a)
    {
        a.readFrom(is);
        return is;
    }
    
    void Student::readFrom(istream& is){
        is >> age;
    }
    
    void Student::setAge(int value){
        age = value;
    }
    
    int main()
    {
        Student a;
        int age;
        cout << "input age of the student: "<< endl;
        cin >> age;
        a.setAge(age);
        cout << "Age of Student is " << a.getAge() << "?";
    }
    

    【讨论】:

      【解决方案3】:

      其实你的例子有很多要点。

      首先,setter 应该有一个参数。按照惯例,setter 总是得到一个改变类的参数,然后 getter 是无参数的,应该是 const

      其次,您的 setAge 实现直接访问 std::cin。如果您查看我的示例,您会发现我确实使用了 is 参数。这将 setAge 与参数的来源分开,并允许更好的 OOD。

      第三,我的实现还提供了更好的抽象,因为输入流可以是任何流(例如文件,或者来自互联网的流)

      #include <iostream>
      
      using namespace std;
      
      class Student
      {
      private:
          int age;
      public:
          Student() : age(0){}
          Student(int age1) : age(age1) {}
          void setAge(int age1);
          int getAge() const { return age; }
          friend istream& operator >> (istream& is, Student& a);
      };
      
      istream& operator >> (istream &is, Student& a)
      {
          int age1;
          is >> age1;
          a.setAge(age1);
          return is;
      }
      void Student::setAge(int age1){
          age = age1;
      }
      
      int main(int argc, char* argv[])
      {
          Student a;
          cout << "input age of the student: " << endl;
          cin >> a;
          cout << "Age of Student is " << a.getAge() << "?" << endl;
      
          return 0;
      }
      

      【讨论】:

        【解决方案4】:

        我没有使用is

        是的,你做到了。您只是从不同的功能中使用它,仅此而已。

        这是同一个流,因为在这两种情况下都是cin

        如果您想从不同的流中提取数据,那么您的代码就会被破坏。这就是为什么我们更喜欢使用 operator&gt;&gt; 的参数而不是猜测它是什么 (cin)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-16
          • 2015-06-27
          • 2015-06-13
          • 2013-10-10
          • 2011-09-23
          • 2017-06-17
          • 2023-03-15
          • 2015-02-16
          相关资源
          最近更新 更多