Thread: Overloading >>

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485

    Overloading >>

    Hallo,

    I am trying to overload the >> sign, but I cant get it to work. Any one know what is wrong?

    Code:
    class Point
    {
          public:
                 void operator>>(ifstream &input, const Point &p);
                 ...
    }
    
    void Point::operator>>(ifstream &input, const Point &p)
    {
         input >> p.x >> p.y;
    }
    declaration of `operator>>' as non-function
    Thank

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You can't overload a binary operator like that inside a class. Make it a function outside the class. If it needs access to private internals of Point, then make it a friend.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Just to be clear, you can overload binary operators inside a class, but this one would have to be overloaded inside the ifstream class rather than the Point class because the ifstream is on the left side of the operator. Since you aren't allowed to change ifstream, the solution is to make it a non-member function.

    Normally, and operator>> looks like this:
    Code:
    istream& operator>>(istream& input, MyClass& o)
    {
      // Do input into o.
      return input;
    }
    Notice that it uses istream instead of ifstream so that it will work on any input stream (like cin or an ifstream). Also notice that it returns input so that you can chain the operator: cin >> point1 >> point2. Finally, notice that the MyClass reference is not const, because you are changing o (or in your case p).

    Of course, the other difference is that you often need the operator to be a friend as brewbuck indicated.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Thanks for the replies. I tried both of the things you posted before I created my post, but it did not work...forgot the namespace

    Here is what I ended up with
    Code:
    friend std::ifstream &operator>>(std::ifstream &input, Point &p);
    Should the input be const? I cant see any reasons for it to not be...

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Should the input be const? I cant see any reasons for it to not be...
    You are modifying p by setting x and y to new values.

    Also, is there a reason you are choosing to use ifstream instead of istream?

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    >> Should the input be const? I cant see any reasons for it to not be...
    You are modifying p by setting x and y to new values.
    I change the point, not the std::ifstream &input, or is that change somehow as well?

    Also, is there a reason you are choosing to use ifstream instead of istream?
    I have only used ifstream before, so it was easier there and then.

    Code:
    istream& operator>>(istream& input, MyClass& o)
    {
      // Do input into o.
      return input;
    }
    Why would you return input?

    The way I understand it is like this:
    Take input and pass it to >>
    Assign value to Point
    Return input back to input <--- Does not make sense to me

    Where am I wrong?

    Thanks for the replies so far.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I change the point, not the std::ifstream &input, or is that change somehow as well?
    Oh, sorry. Yes, you are changing input as well because the text is being read from the stream and so the stream will be in a different state after you read from it.

    >> I have only used ifstream before, so it was easier there and then.
    Ok. The reason you use istream is that it is the base class of ifstream and allows you to use your operator with stringstreams or cin. If you are only using ifstreams and don't want to use code you haven't learned then that's fine, just know for the future that istream is the better solution.

    >> Why would you return input?
    Take code like this:
    Code:
    std::ifstream in("points.txt");
    Point p1, p2;
    
    in >> p1 >> p2;
    That last line is just calling the operator>> function twice. It goes from left to right:
    Code:
    (in >> p1) >> p2;
    If you change it to function notation it looks like this:
    Code:
    operator>>(operator>>(in, p1), p2);
    The function in blue is called first. Then the return value of that function is passed to the function in red. You want to pass an input stream as the first parameter to the function in red, which is why the operator>> has to return that input stream. The return value is just ignored if you don't combine operators.

    Also, remember that input is modified by the values being read from it for p1, so we have to pass the modified stream to the second call so that p2 gets the next set of values from the stream instead of the same ones as p1.
    Last edited by Daved; 05-05-2008 at 06:54 PM.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Thank you very much Daved.

    I might change it to istream later, but for this project there is really no points of doing it. The points will always be in a file. And there is no other use for them. If I am ever to use a point class in a personal project I will write a new one, this one has to many weird things in it (My teachers want me to do horrible things.. )

    One last question:

    I assume that input is passed as a reference due to speed? If the input is really big it will take time to copy it. But would not returning input defeat the purpose of the reference as the return will copy the value of input.

    My writing is horrible today, hope it makes some sense.
    Thanks

  9. #9
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    The return value of the function is also a reference.

  10. #10
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Thanks for pointing that out, feel stupid now.

    Thanks for all the help on this

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by h3ro View Post
    I assume that input is passed as a reference due to speed?
    Streams are non-copyable. Why, I'll leave to other people.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you copy a stream and start reading (or writing) from both copies, then it gets very confusing as to what should be getting read (or written) from (or to) where.

  13. #13
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    I am having some more problems with the >> operator.
    I can input Points with >> as long as there is nothing else going on in the same line. Eg, this works:
    input >> Point

    but this does not
    input >> string >> Point

    Any ideas on what I am doing wrong? It might have something to do with inheritance maybe?

    Code:
    class Car
    {
          public:
                 ...
                 
          protected:
                    string name;
                    Point pos;  
                    ...  
    };
    
    class RaceCar : public Car
    {
          friend std::ifstream &operator>>(std::ifstream &input, RaceCar &car);
          
          public:
                 ...
     
          private:
                  int size;  
                  ...   
    }
    
    std::ifstream &operator>>(std::ifstream &input, RaceCar &car)
    {
        input >> car.name >> car.size >> car.position;
        return input;            
    }
    Thanks

  14. #14
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Well it is hard to tell, but the problem may go away if you turn your ifstreams (in the operator overload) into istreams as already suggested.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Daved View Post
    If you copy a stream and start reading (or writing) from both copies, then it gets very confusing as to what should be getting read (or written) from (or to) where.
    I think the bigger problem is that an ifstream is a RAII object which closes the file when it goes out of scope. So if you were allowed to make copies, either one object would close the resource out from under the other, or the ifstream would have to somehow duplicate the file handle, which isn't necessarily possible on all platforms.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overloading << and >>
    By MMu in forum C++ Programming
    Replies: 1
    Last Post: 04-21-2008, 06:49 AM
  2. Overloading fstream's << and >> operators
    By VirtualAce in forum C++ Programming
    Replies: 2
    Last Post: 04-09-2007, 03:17 AM
  3. << and >> overloading
    By Armatura in forum C++ Programming
    Replies: 2
    Last Post: 12-07-2003, 06:19 PM
  4. Overloading the << and >> operators
    By WebmasterMattD in forum C++ Programming
    Replies: 9
    Last Post: 10-15-2002, 05:22 PM
  5. istream >> overloading
    By wazza13 in forum C++ Programming
    Replies: 1
    Last Post: 05-03-2002, 10:56 PM