Creating a function for stream objects

Started by
7 comments, last by Zahlman 19 years, 7 months ago
Question: How do you create a function/class that can be called using a stream? Something like this: class Cat { public: function operator<<(); // <- I know this is wrong private: string s1; int i1; }; function operator<<() { output the varibles to a ostream } main() { cout << Cat; } (yes, I know the code wont compile and doesn't initialize data, etc... I just someone to explain how to use << so I can have my classes save there data to a ostream using something like this) I have looked everywhere, this site and others, and can find no clear cut example (maybe Im looking in the wrong places...)
Advertisement
#include <iostream>#include <string>class Cat{	public:		// member functions	private:		std::string descriptiveName;		int anotherDescriptiveName;};std::ostream& operator<<(std::ostream& stream, const Cat& cat){	// output the varibles to a ostream	return stream;}int main(){	Cat c;	std::cout << c;}


Enigma

EDIT: forgot to make the cat parameter of operator<< const.
Since all the variables are private, you'll also want to have public get methods or else declare the function in the class as

friend std::ostream& operator<<(std::ostream& stream, const Cat& cat);

So that the private members are visible to the function.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
That or have the operator<< delegate to a virtual print(std::ostream&) member function to do the stream insertions.
I figured it out...

Here I have my class...

class WackyCat
{
data and functions and things, oh my!
}

Then, I do this:

ostream& operator<<(ostream& os, WackyCat &uWCat)
{
os << uWCat.whatevermemberfunction() << " ";
os << uWCat.whateverelsememberfunction() << " ";
return os;
}

It works pretty good! Anyone see any problems with it?
Looks OK to me. I'd make it take a const reference to the WackyCat instance though so the function isn't allowed to modify the data whilst outputting it.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
Could also add some localization support, and using a virtual print member function could help remove the get functions from the class interface, and also allows you to output to the stream polymorphically to a greater extent than you can with your current implementation.
//////////////////////////////////////////////////////
Looks OK to me. I'd make it take a const reference to the WackyCat instance though so the function isn't allowed to modify the data whilst outputting it.
//////////////////////////////////////////////////////
Sounds good, I'll add the const thingy so the data wont change.

/////////////////////////////////////////////////////
Could also add some localization support, and using a virtual print member function could help remove the get functions from the class interface, and also allows you to output to the stream polymorphically to a greater extent than you can with your current implementation.
//////////////////////////////////////////////////////
I haven't the faintest idea what your talking about, but thanks for helping... (I'm a beginner).

What the other guy is saying with the virtual print member functions is something like:
class WackyCat {  public:  virtual ostream& printTo(ostream& os) {    // do stuff for printing a 'normal' WackyCat:    os << foo() << " " << bar() << " ";    // and you can print data here too, even private stuff.    // When I was in university, they taught me to handle     // this by making ostream a friend class so that it could    // access the needed public data directly. IMHO that's an    // awful way of doing things though.    return os;  }}class WackierCat: public WackyCat {  public:  ostream& printTo(ostream& os) {    // print different stuff because this cat is wackier!    os << bar() << " " << baz() << " ";    return os;  }}ostream& operator<<(ostream& os, const WackyCat &uWCat) {  uWCat.printTo(os);  // at runtime, this will check which kind of WackyCat you have  // and call the appropriate printTo() method.  return os;}


In Java, the paradigm is that every Object can provide a toString() method, which is called when needed for outputting. I suppose you could do something like this in C++, by implementing "operator std::string()", but then you get into some of C++'s weirder implicit-conversion idiosyncrasies eventually, and also will probably need a strstream when you write your implementation (so that it's kind of self-defeating).

This topic is closed to new replies.

Advertisement