Solved

How to overload the << and >> operators?

Posted on 1998-12-05
19
263 Views
Last Modified: 2013-12-14
I have been told that it is possible to overload the << and >> iostream operators so that it becomes possible to write a line of code like:

cin>>myclassobject;

but I have also heard that it's kinda complicated and involves friend classes or something.

What I'm looking for is some sample code using some arbitrary class definition like this one:

class myclass {
  private:
    int a;
  public:
    // operator>> function prototype
    // operator<< function prototype
  };

anyone?  It's worth a lot of points to me to learn how to do this...
0
Comment
Question by:ris
  • 8
  • 6
  • 5
19 Comments
 
LVL 1

Expert Comment

by:Booth882
Comment Utility
yeah sure its not too hard.  you have to make it a friend function so that you can access your data without convoluted bypassing.  heres the syntax.

friend ostream & yourclass::operator<<(ostream & Stream, yourclass & Instance)
{
   // code here

   return Stream;
}

you have to adjust the stream sent into the function, so to cout say a double you would say

   Stream << MyDouble;

you dont actually use cout in the function call.  same thing for cin except its istream instead of ostream.  any questions?
0
 
LVL 1

Expert Comment

by:Booth882
Comment Utility
ahh sorry I made a mistake.  in the class declaration it would go:

friend ostream & operator<<(ostream &, yourclass &);

and in the implementation it would go:

ostream & yourclass::operator<<(ostream & Stream, yourclass & Instance)
{
   // code here

   return Stream;
}

the friend declaration is in the class declaration only.  
0
 
LVL 1

Author Comment

by:ris
Comment Utility
Let me just make sure I understand how to do this...

If I understand you correctly, for a class that had only one integer data member (like the simple example I wrote in above) it would look like this?

class myclass {
  private:
    int a;
  public:
    friend ostream& operator<<(ostream& Stream, myclass X)
      {Stream<<X.a;
      return Stream;
      }
    friend istream& operator>>(istream* Stream, myclass X)
      {Stream>>X.a;
      return Stream;
      }
  }; //end class

Will that work?
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
don't declare inside class declarations...

here is the code you need:

class myclass {
  private:
    int a;
  public:
    friend std::istream & operator>>(std::istream & s, myclass & obj);
    friend std::ostream & operator<<(std::ostream & s, myclass const & obj);
  };

std::ostream & operator<<(std::ostream & s, myclass const & obj)
{
    return s << obj.a;
}

std::istream & operator>>(std::istream & s, myclass & obj)
{
    s >> obj.a;

    return s;
}

more to come...
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
if your class has multiple members, say std::string name and long phonenumber, then the output could be like this (for example):

//...
    return s << obj.name << " (phone: " << obj.phonenumber << ")"
//...

yielding eg.: "yourname (phone: 1234567890)"

assuming you want to input this data by typing a single name followed by a space and a phonenumber, then your input would look like this:

//...
    s >> obj.name >> obj.phonenumber;
//...

reading a std::string from an istream terminates at a whitespace. If you want to read in full names, you should probably use the getline function to read the whole line
(formatted such as: "first i. lastname, 1234567890")
and then parse the resulting string for the comma and split the two atoms into the variables of the myclass object.

ie:
//...
    std::string temp;
    getline(s, temp);
    // now parse temp and split the first part into obj.name,
    // and convert the part after the ", " sequence into a long
    // with obj.phonenumber = atol(temp.c_str());
//...

have fun.


0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
but, of course, I am only elaborating on Booth because he was a little quicker. Don't want to steal his points, so if you are fine with his answer, give him the points, and if you feel that I helped you, then give them to me.
0
 
LVL 1

Expert Comment

by:Booth882
Comment Utility
yeah madduck it seems like my answer was correct, it answered his question as far as he asked it.  your elaboration is welcome I'm sure but it didnt add anything to the answer to his question, and it seems to me kind of a low down dirty trick to try and swoop in and take the points.  but if you really care about the points that much you can go ahead and have them.

ris I dont understand why you rejected my answer?  but if your question has been answered then EE has served its purpose and all is well.  just keep in mind you dont have to reject an answer to receive clarification.  
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
it was not supposed to be a trick...therefore the comment.            
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
ris->
you want to reject my answer and give booth the points please.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Author Comment

by:ris
Comment Utility
I've suggested to the people at EE to allow points to be awarded to people who comment on a question, but they have yet to answer my request, so I'm forced to reject your answer in order to award the points to booth.

Thanks to both of you, though - I really appreciate the help and the elaborate clarifications!  In the future, I'll just accept the answer and ask for a clarification anyway...sorry about that.

p.s. please do not submit an answer unless you are booth882
0
 
LVL 1

Author Comment

by:ris
Comment Utility
I've suggested to the people at EE to allow points to be awarded to people who comment on a question, but they have yet to answer my request, so I'm forced to reject your answer in order to award the points to booth.

Thanks to both of you, though - I really appreciate the help and the elaborate clarifications!  In the future, I'll just accept the answer and ask for a clarification anyway...sorry about that.

p.s. please do not submit an answer unless you are booth882
0
 
LVL 1

Accepted Solution

by:
Booth882 earned 200 total points
Comment Utility
thanks ris.  and no hard feelings madduck, I know you didnt mean anything malicious by it.  its hard sometimes to give points to just one expert, very often there are many experts who contribute to an answer and deserve to be rewarded for it.  there is no justice I guess, not even in experts exchange!
0
 
LVL 1

Author Comment

by:ris
Comment Utility
What do I have to include to get the std:: object/namespace ?

I included iostream.h and fstream.h, but apparently there's something else I need because my compiler (Borland) says "std is not a class or namespace name."

help...?
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
just include <iostream>...this is the proper C++ STL header.

iostream.h is simply somthing like this:

//...
using namespace std;
#include <iostream>
//...

so it gets rid of the std namespace.
0
 
LVL 1

Author Comment

by:ris
Comment Utility
I added the line "using namespace std;" but now it tells me "expected namespace name" on the std part of that line.

I tried reordering the #include <iostream.h> before and after the "using namespace std;" line and I also tried removing the ".h" from <iostream.h> but no permutations of that change anything.

What am I doing wrong?  Here is my code.

#ifndef _NEURAL_NETWORK_NODE_
#define _NEURAL_NETWORK_NODE_

using namespace std;
#include <iostream>

#define maxinputs 5000
#define random_decimal_places 3
#define minout 0
#define maxout 1

//#define debugout cout

class node {
  private:
    int n; //the number of inputs to this node
    float* weights;
    float b;
    float last_result;
    float* last_inputs;

    float squash(float x);
    float dsquash(float x);
   
  public:
    node() {};
    node(int inputs); //initializes weights randomly
    node(int inputs, float x); //initializes weights to x

    void initialize_weights(); //randomly
    void initialize_weights(float x); //all to the value of x
    float run(float inputs[maxinputs]);
    void adjust_weights(float error);
    float* calculate_blame(float error);

    friend std::istream& operator>>(std::istream& s, node& n);
    friend std::ostream& operator<<(std::ostream& s, node& n);
   
    void debug(); //prints the state of the node
  }; //end node class

#endif //defined _NEURAL_NETWORK_NODE_
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
do you want the namespace to be put into the global namespace or not. ie: do you want to use std::cout or cout?

if you want std::cout, then include <iostream>
if you want cout, then include <iostream.h>

don't specifically state 'using namespace std;' I was just citing iostream.h...
0
 
LVL 1

Expert Comment

by:Booth882
Comment Utility
yeah I personally have never seen "std::cout" used.  I have always said:

#include <iostream.h>

and that seems to work for me.  

hey ris you are into neural networks???  I have done some neural network work myself, and am very interested in that kind of thing.  what kind of things are you planning to do with them?

madduck, have you seen my "making an environment" question in the lounge?  I was thinking you would have some interesting comments to add.  maybe you should both check it out.
0
 
LVL 1

Author Comment

by:ris
Comment Utility
So I can use #include<iostream.h> and remove all of the "std::" from everywhere?

Booth: I'm using a neural network to analyze facial images to determine the gender of the face.  I'm also working on a graphic file decoder to extract the RGB pixel data from the facial image files...which has to do with another question that I've posted in this area.
0
 
LVL 8

Expert Comment

by:MaDdUCK
Comment Utility
you can only remove the std::'s from the classes, types, and functions declared in iostream.h. For instance, you cannot remove std:: from std::string. To do the latter, you would have to include <string.h> as opposed to <string>. This scheme works for every STL library.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now